2010-08-26 50 views
1

我有一個實體(比如說User)有一個實體列表(比如List)的數據庫。作爲一個要求,我必須有名單上的實體的非規範化數:使用EntityListener級聯修改實體

@Entity 
class User { 
    /* ... */ 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private List<Friendship> friends; 

    public int friendsCount; 
    /* ... */ 
} 

當我添加新元素到列表中,我必須,事務,增加相應的計數器。

我試圖做這樣使用一個EntityListener:

​​

實體監聽器的調用是否正確,並在調試時我可以看到它正確地修改實體。但是,Hibernate不向數據庫發送UPDATE查詢,只發送INSERT查詢(對應於友誼實體)。

我已經在EntityListener上嘗試了不同的事件,但它似乎沒有工作。

我想這裏發生的是實體監聽器是由用戶更新觸發的。然後它識別用戶的所有髒屬性,其中僅包含List。因此它對用戶沒有任何關係,只需要插入友誼。然後它將操作級聯到友誼。實體監聽器被調用,它修改了用戶,但是此時Hibernate已經確定它不必擔心用戶,因此它不更新用戶。

這個推理是否正確?

如果是這樣,我該如何正確實現?

感謝, 布魯諾

回答

0

我曾嘗試在EntityListener不同的事件,但它似乎並沒有工作。

從我所看到的,UserFriendship之間的一個一對多的關聯是雙向的,但你的映射不反映這一點。那麼你能先修正你的映射嗎?事情是這樣的:

@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
  • 我添加了一個方便的方法來設置的兩面鏈接正確添加Friendship

實體監聽器被調用時,它會修改用戶的時候,但此時Hibernate已經確定它不必擔心用戶,因此它不會更新用戶。

MyBrokenEntityListener聽衆對我的作品,我無法重現使用上述固定的映射問題:Hibernate沒有檢測User實例監聽器調用之後陳舊的,它並觸發更新。以下測試方法(在交易中運行)通過:

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

嗨,帕斯卡。實際上,我在我的真實代碼上使用了「mappedBy」參數,只是忘了在這裏寫例子。我會再試一次,並告知你。謝謝! – 2010-08-27 13:26:10

+0

@布魯諾添加朋友時,您是否也正確設置了鏈接的正反兩面?順便說一句,我使用了Hibernate 3.5.x。 – 2010-08-27 16:09:27