2015-01-15 81 views
0

我有奇怪的行爲與@Transactional註釋。該代碼使用@Transactional行之有效的呼叫者@Transactional上一個名爲Bean內部的公共方法:HHH000437

import org.springframework.transaction.annotation.Transactional; 

private javax.persistence.EntityManager em; 

@Transactional 
public void caller(String login) { 
    callee(login); 
} 

public void callee(String login) { 
    user = new User(login); 
    em.persist(user); 
    userInfo = new UserInfo(); 
    userInfo.setUser(user); 
    em.persist(userInfo); 
} 

但是下面執行第二em.persist被叫返回錯誤使用@Transactional:

import org.springframework.transaction.annotation.Transactional; 

private javax.persistence.EntityManager em; 

public void caller(String login) { 
    callee(login); 
} 

@Transactional 
public void callee(String login) { 
    user = new User(login); 
    em.persist(user); 
    userInfo = new UserInfo(); 
    userInfo.setUser(user); 
    em.persist(userInfo); // ERROR: org.hibernate.action.internal.UnresolvedEntityInsertActions : HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities. 
} 

錯誤返回:

org.hibernate.action.internal.UnresolvedEntityInsertActions : HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.  
Unsaved transient entity: ([package.entities.User#<null>]) 
Dependent entities: ([[package.entities.UserInfo#<null>]]) 
Non-nullable association(s): ([package.entities.UserInfo.user]) 

有人有想法嗎?

謝謝!

+1

Spring使用代理申請AOP,這基本上意味着,唯一的方法調用到(外部)對象檢索AOP,內部方法通過代理來調用。 – 2015-01-16 06:52:13

回答

2

我認爲這是因爲Spring會在您的類的周圍創建代理Bean,並且只有代理的方法纔會使用帶註釋的行爲進行增強。當您註釋一個私有方法時,它將從您的類中調用,並且不能通過代理調用,導致註釋被忽略。

@M。 Deinum是正確的,我認爲,我的答案的正確版本。因此,只有註釋的方法具有事務支持,但如果通過彈簧代理調用,則只有。如果你像bean那樣從bean本身調用它,它將不起作用。

爲了這個工作,你將不得不使用這樣的事情

context.getBean(MyBean.class).callee(login); 
+0

對不起,在我的問題中有一個錯誤:兩種方法都是公開的,沒有私人的 – Pleymor 2015-01-16 06:31:06

+0

這種方法是否是私人的(我們可以看到它是公開的)並不多。相反,這意味着這是一個bean實現類,並且該接口沒有第二個'callee'方法。在這種情況下,Spring AOP不能代理該方法。是這樣嗎? – Steve 2015-01-16 08:57:04

+0

@Steve第二種方法在原始問題中是私人的。無論如何,你的理論對我來說很有意義。 – 2015-01-16 09:05:57

相關問題