我的团队有两个类User
和Store
,与JPA @ManyToMany
注释相关。相关代码如下。
创建新的User
对象并设置其商店时,生活是美好的。但是当我们尝试通过Struts 2 / Spring Web UI更新User对象时,我们看到了一些意想不到的行为。 (通过JUnit运行简单的自动化集成测试时不会出现这些问题。)
简单地说,在保存User
时,其商店集合未更新 - 数据库显示没有更改,并且有问题的User
对象的重新加载显示它具有未更改的商店集
我们发现这个问题的唯一解决方案 - 我们不喜欢这个解决方案,它让我们团队中的所有开发人员都感到有些不安 - 就是创建一个新的Set
{ {1}} s,然后执行Store
,然后执行user.setStores(null)
。
我们正在使用user.setStores(stores)
;我们使用Hibernate作为我们的JPA提供者;我们正在使用Spring的JpaTransactionManager。我们的代码中没有任何OpenEntityManagerInViewFilter
注释 - 由于其他地方描述的代理行为,添加它们会破坏现有代码。
任何人都可以提供有关我们如何以不安静的方式解决此问题的任何见解,这是值得欢迎的。
User.java的相关部分:
@Transactional
Store.java的相关部分:
@ManyToMany
@JoinTable(name = "company.user_store_access",
joinColumns = @JoinColumn(name = "userid"),
inverseJoinColumns = @JoinColumn(name = "storeid"))
public Set<Store> getStores() {
return stores;
}
UserDetailAction.java的相关部分: (通过一层或两层,然后:)
@ManyToMany(mappedBy = "stores")
public List<User> getUsers() {
return users;
}
答案 0 :(得分:6)
问题在于你有一个双向关系,在这种情况下,有一个实体控制另一个,从你的映射控制的是商店实体,而不是< strong>用户,因此将用户添加到商店会起作用(因为商店是控件的商店)但是向用户添加商店不会。
通过在getStores()方法上放置@ManyToMany(mappedBy =“users”)注释并更改getUsers(),可以尝试通过使User对象成为控制关系的对象来反转这种情况。希望它有所帮助。
P.S。控制关系的实体始终是没有mappedBy属性的实体。
答案 1 :(得分:2)
我只是遇到了同样的问题,并在另一页上找到了解决方案。
这是对我有用的东西
在调用merge之前调用getJpaTemplate()。flush()对我有用。
我没理解它起作用的原因。
答案 2 :(得分:1)
请在用户对象中尝试以下注释:
@ManyToMany(cascade = {CascadeType.ALL})