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());
}