【发布时间】:2011-09-29 15:12:44
【问题描述】:
我想用 JPA/Hibernate 为两个实体、一个组和一个帐户之间的关系建模。一个帐户可以有多个组,但反之不行,因此我们在帐户和组之间建立了 OneToMany 关系。
我的工作同事建议对实体 Account 和 Group 进行建模
public class Account {
private List<Group> groups = new ArrayList<Group>();
public Account() {}
public void setGroups(List<Group> usergroups) {
this.groups = groups;
}
@OneToMany(mappedBy = "account")
public List<Group> getGroups() {
return groups;
}
}
和
public class Group {
private String name;
private Account account;
public Group() {}
public Group(String name, Account account) {
this.name = name;
addToAccount(account);
}
public void addToAccount(Account account) {
setAccount(account);
List<Group> accountGroups = account.getGroups();
accountGroups.add(this);
}
@ManyToOne
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
我现在的问题是关于Group 的构造函数中辅助方法addToAccount 的使用。根据我的工作同事的说法,这种方法是必要的,因为我们需要从双方更新两个实体之间的双向关系,以确保两个实体的内存模型一致。
但是我相信在构造函数中调用方法addToAccount不是一个好主意,因为
Groups的List懒惰 获取,所以调用该方法addToAccount需要打开 交易。所以构造函数Group只能在内部调用 打开交易。在我看来,这是一个非常烦人的限制。Account对象作为参数给出Group的构造函数是 由构造函数更改。在我看来,这是一个Group令人惊讶的副作用 构造函数,不应该发生。
我的建议是更好地使用简单的构造函数,例如
public Group(String name, Account account) {
this.name = name;
this.account = account;
}
并手动处理双向关系。但也许我错了。在构建休眠实体时,是否有一种常见的方式来处理双向关系?
【问题讨论】:
-
我相信你们大学的提议是不好的做法。不仅关于 1 或 2(特别是 2!),在此之上,您应该在构造函数中使用可覆盖的方法,因为它可以在子类中有效地被覆盖并在子对象构造函数 get 被调用之前被调用!我确实相信你应该保持一个一致的对象图(内存模型),我正在研究如何最好地做到这一点并解决这个问题.. 只是无法静音!你终于得到答案了吗?
标签: java hibernate constructor side-effects bidirectional-relation