我目前在一个项目中使用Hibernate,但无法建立多对多关系。我认为我的问题与级联类型有关。

场景是我们有一个广告,每个广告可以有很多标签,但是每个标签可以与很多广告相关。广告实体的ManyToMany注释是:

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
@JoinTable(name = "adMediaAdvertiserTag",
        joinColumns = { @JoinColumn(name = "adMediaId") },
        inverseJoinColumns = { @JoinColumn(name = "advertiserTagId") })


标签实体上的ManyToMany映射为:

@ManyToMany(mappedBy = "advertiserTags", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })


我看到两个不同的错误,具体取决于级联类型的配置以及该标记是否已存在于数据库中。

如果广告上的级联类型不包含PERSIST并且该标记尚不存在,那么我们会遇到以下异常:

TransientObjectException: object references an unsaved transient instance


如果广告上的级联类型确实包含PERSIST并且标签已经存在,我们将得到:

PersistentObjectException: detached entity passed to persist


我可以使该工作正常运行的唯一方法不是将PERSIST作为级联类型,而是遍历每个标记并将它们保存到会话中。

这是正确的方法吗?休眠有办法自动为我处理吗?

让我知道是否不清楚,或者您需要更多信息。

更新

我正在使用使用springframework的CrudRepository对象的save方法的服务来保存对象。有很多代码,所以我无法真正发布所有代码。

我目前不为我要保存的任何对象调用任何合并或持久方法。我印象中,Hibernate会为我处理这类事情。

最佳答案

您能否添加用于保留Advert和Tag对象的代码。我使用以下代码(我认为与您的代码相似)进行了测试,并且可以正常工作:

User user = new User();
Role role = new Role();
role.setId("TEST_ROLE");
user.getRoles().add(role);

entityManager.persist(user);

User user2 = new User();
user2.getRoles().add(role);
entityManager.persist(user2);
System.out.println(user2.getId());


在用户我有:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinTable(name = "user_roles",
        joinColumns = {@JoinColumn(name = "user_id", nullable = false, updatable = true)},
        inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false, updatable = true)})
protected List<Role> roles = new ArrayList<>();


我的角色是:

@ManyToMany(mappedBy="roles")
protected List<User> users;

关于java - hibernate 多对多级联类型问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36449053/

10-10 08:54