我的Java EE 6应用程序中的域模型包含双向关系,如下所示:
@Entity
public class Users implements PrimaryKeyHolder<String>, Serializable {
@Id
private String username;
@ManyToMany(mappedBy= "users")
private List<Category> categories;
public List<Category> getCategories() {
if (categories == null) {
categories = new ArrayList<Category>();
}
return Collections.unmodifiableList(categories);
}
public void addCategory(Category category) {
if (categories == null) {
categories = new ArrayList<Category>();
}
categories.add(category);
if (!category.getUsers().contains(this)) {
category.addUser(this);
}
}
public void removeCategory(Category category) {
if (categories == null) {
categories = new ArrayList<Category>();
}
categories.remove(category);
if (category.getUsers().contains(this)) {
category.removeUser(this);
}
}
public void setCategories(Collection<Category> categories) {
if (this.categories == null) {
this.categories = new ArrayList<Category>();
}
for (Iterator<Category> it = this.categories.iterator(); it.hasNext();) {
Category category = it.next();
it.remove();
if (category.getUsers().contains(this)) {
category.removeUser(this);
}
}
for (Category category : categories) {
addCategory(category);
}
}
}
@Entity
public class Category implements PrimaryKeyHolder<Long>, Serializable {
@Id
private Long id;
@ManyToMany
private List<User> users;
public List<User> getUsers() {
if (users == null) {
users = new ArrayList<User>();
}
return Collections.unmodifiableList(users);
}
protected void addUser(User user) {
if (users == null) {
users = new ArrayList<User>();
}
users.add(user);
}
protected void removeUser(User user) {
if (users == null) {
users = new ArrayList<User>();
}
users.remove(user);
}
}
更新:我添加了关系管理代码。关系仅在用户端设置,因此,添加/删除方法在Categoriy类中受到保护。我通过setCategories
为用户设置了类别。
Eclipselink正确生成了一个连接表CATEGORY_USERS。但是,它不会在其中保留任何信息(它只会缓存信息)。例如。当我在实体管理器(例如用户)上执行查找操作时,它返回完整的对象图(包括类别关系)。但是当我查看表格时,信息不会更新(即使事务已提交)。我还在我的代码中插入了一个flush操作,但没有成功。正确保存和更新基本信息(如String,Integer等列)。将日志级别转换为FINE后,我可以看到没有为关系和连接表执行任何SQL语句。但我确实看到了单向关系的SQL语句。
我的数据模型涵盖了广泛的单元测试,所有单元测试都成功通过。我基本上执行与容器相同的操作,提交事务,从db重新加载实体并检查关系是否正确设置,它们是什么(我正在使用内存中的derby数据库进行测试)。 p>
我的应用服务器是Glassfish v3.1-b17。
感谢任何帮助。 谢谢, Theo
答案 0 :(得分:3)
确保您正在设置关系的两个方面。规范要求应用程序设置关系的两个方面,因为JPA中没有关系维护。
答案 1 :(得分:1)
经过无数次的尝试后,我终于得到了一个解决方案:我只是改变了关系的拥有方,即我将mappedBy属性放到类别实体中,如下所示:
@ManyToMany(mappedBy= "categories")
private List<User> users;
可以找到here
的解释答案 2 :(得分:0)
四点:
1.-当您遇到错误时,更简单的找到解决方案在一个再现错误的示例(或单元测试)中隔离它们。在您的情况下,您可以使用更简单的getter和setter做一个示例(例如,删除unmodifiableList用法以及其他用于测试实际问题的必要方法)。
2.-我建议你使用 pojos for model ,没有任何逻辑。所以,从pojos中删除逻辑。
3.-我们正在使用eclipselink,我们没有持久关系的问题。因此,错误更有可能出现在您的代码中。
4.-使用“cascade = javax.persistence.CascadeType.ALL
”
为我可怜的英语道歉:(