Hibernate 使用级联上的EntityListener修改实体
我有一个数据库,其中一个实体(比如用户)有一个实体列表(比如列表)。作为要求,我必须对列表中的实体进行非规范化计数:Hibernate 使用级联上的EntityListener修改实体,hibernate,orm,jpa,cascade,entitylisteners,Hibernate,Orm,Jpa,Cascade,Entitylisteners,我有一个数据库,其中一个实体(比如用户)有一个实体列表(比如列表)。作为要求,我必须对列表中的实体进行非规范化计数: @Entity class User { /* ... */ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Friendship> friends; public int friendsCount; /* ... */ }
@Entity
class User {
/* ... */
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Friendship> friends;
public int friendsCount;
/* ... */
}
实体侦听器被正确调用,在调试时,我可以看到它正确地修改了实体。但是,Hibernate不向数据库发送更新查询,只发送插入查询(对应于友谊实体)
我在EntityListener上尝试了不同的事件,但似乎不起作用
我认为这里发生的是,实体侦听器是由用户的更新触发的。然后,它标识用户的所有脏属性,这些脏属性仅由列表组成。因此,它与用户无关,只需插入友谊即可。然后将操作级联到友谊。实体侦听器被调用,它修改用户,但此时Hibernate已经确定它不必担心用户,因此它不会更新用户
这个推理正确吗
如果是的话,我怎样才能做到这一点
谢谢,
布鲁诺
我在EntityListener上尝试了不同的事件,但似乎不起作用
从我所看到的,用户
和友谊
之间的一对多关联是双向的,但您的映射没有反映这一点。那么你能先修复你的映射吗?大概是这样的:
@Entity
public class User1 {
@Id @GeneratedValue
private Long id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "user1")
private List<Friendship> friends = new ArrayList<Friendship>();
public int friendsCount;
// omitting getters, setters for brevity
public void incrementFriendsCount() {
friendsCount++;
}
public void addToFriends(Friendship friend) {
this.getFriends().add(friend);
friend.setUser1(this);
}
}
嗨,帕斯卡。实际上,我在实际代码中有“mappedBy”参数,只是忘了在这里写示例。我会再试一次,并随时通知你。谢谢@Bruno添加好友时,您是否也正确设置了链接的两侧?顺便说一下,我使用了Hibernate3.5.x。
@Entity
public class User1 {
@Id @GeneratedValue
private Long id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "user1")
private List<Friendship> friends = new ArrayList<Friendship>();
public int friendsCount;
// omitting getters, setters for brevity
public void incrementFriendsCount() {
friendsCount++;
}
public void addToFriends(Friendship friend) {
this.getFriends().add(friend);
friend.setUser1(this);
}
}
@Test
public void testPostPersistInvocationOnAddFriend() {
User1 user = new User1();
Friendship friend1 = new Friendship();
user.addToFriends(friend1);
em.persist(user);
em.flush();
assertEquals(1, user.getFriendsCount());
Friendship friend2 = new Friendship();
user.addToFriends(friend2);
em.flush();
em.clear(); // so that we reload the managed user from the db
user = em.find(User1.class, user.getId());
assertEquals(2, user.getFriendsCount());
}