多对多 Spring JPA 关系从 get() 不返回任何数据

问题描述 投票:0回答:1

我使用 JPA 在 Spring Boot 应用程序中的两个实体之间添加多对多关系。我有以下映射: 任务类别:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "task_tags_dim",
            joinColumns = {@JoinColumn(name = "task_id")},
            inverseJoinColumns = {@JoinColumn(name = "tag_id")})
    private Set<Tag> tags;

标签类别:

@ManyToMany(mappedBy = "tags", fetch = FetchType.LAZY)
    private Set<Task> tasks;

最终目标是一个任务可以关联多个标签,一个标签可以关联多个任务。但是,似乎无论我尝试将标签添加到任务集多少次,任务集都不会“保存”之前添加的标签,因此

currentTask.getTags()
不会返回任何结果。我看过类似的帖子,但它对我的用例并没有多大帮助:Hibernate 多对多关系返回空集合

这是我的标签服务:

@Service
@Transactional
public class TagService {
    @Autowired
    private TagRepository tagRepository;
    @Autowired
    private TaskRepository taskRepository;

    //create() will create a tag and link it to a specific task
    public Tag create(Tag tag, Long task_id) {
        try {
            Optional<Task> optionalTask = taskRepository.findById(task_id);
            if (optionalTask.isPresent()) {
                Task currentTask = optionalTask.get();
                Tag newTag = new Tag(tag.getName(), tag.getColor());


                //currentTask.getTags().add(newTag);
                //taskRepository.save(currentTask);

                System.out.println(currentTask.getTags().size()); //always returns 0

                Set<Tag> tags = currentTask.getTags();
                tags.add(tag);
                currentTask.setTags(tags);
                taskRepository.save(currentTask);


                return newTag;
            }
        } catch(IllegalArgumentException e) {
            throw new IllegalArgumentException("Tag '" + tag.getName() + "' already exists.");
        }
        throw new NoSuchElementException("Task not found");
    }
}



我在任务类中使用 Cascade.type 的方式有问题吗?

从 taskRepository.findById() 获取任务对象后,我尝试使用 getTags() 检索这些任务的标签,但没有返回任何结果。我还尝试将 Fetch 类型更改为 EAGER,但没有成功。

java spring-boot jpa spring-data-jpa
1个回答
0
投票

您的多对多关系是双向的。当您添加新的加入条目时,您必须将其添加到两侧(两个实体)。在 Post 实体中实现一个辅助方法,如下所示:

public void addTag(Tag tag) {
    tags.add(tag);
    tag.getTasks().add(this);
}

在服务类中,您将像这样调用此方法:

    currentTask.addTag(newTag);
    taskRepository.save(currentTask);

与此类似,您应该实现一个删除加入条目的方法:

public void removeTag(Tag tag) {
    tags.remove(tag);
    tag.getTasks().remove(this);
}

这样您就可以在一处实现,并且关系将正确同步。

基于:https://vladmihalcea.com/the-best-way-to-use-the-manytomany-annotation-with-jpa-and-hibernate/

© www.soinside.com 2019 - 2024. All rights reserved.