2013-10-01 50 views
2

爲什麼一個實體分離以及如何處理?

  1. 我通過stateless服務獲取從數據庫中的一個實體,
  2. 然後修改它在另一個豆和
  3. 然後要通過無狀態的服務將其保存到數據庫中,

我注意到實體已被分離。我認爲,因爲無狀態服務的持久性上下文,實體來自被佔領的存在。 但是,應該使用有狀態服務嗎?
現在保存時我使用EntityManager#find(ClassOfDetachedEntity,PrimaryKeyOfDetachedEntity)來獲得對數據庫中實體的引用,然後將分離的實體分配給它。
但這是這樣嗎?
在我只是堅持複製到數據庫之前,雖然我只是想修改現有的條目。

UPDATE(簡單的例子,以顯示其中 「超脫」 - 問題發生時):

@Stateless 
@Log 
public class DatabaseService implements Serializable { 

    @PersistenceContext 
    EntityManager em; 

    public List<Category> getCategories() { 
     return em.createQuery("SELECT c FROM Category c").getResultList(); 
    } 

    public void checkIfDetached(Object o){ 
     log.info("is detached: " + String.valueOf(!em.contains(o))); 
    } 
} 

豆登錄聲明會告訴我,對象被分離:

@ManagedBean 
    @ViewScoped 
    public class CategoriesBean implements Serializable { 
     private Category testCategory; 

     @PostConstruct 
     public void init(){ 
      testCategory = dbs.getCategories().get(0); 
      dbs.checkIfDetached(testCategory); 
     } 
    } 

回答

1

分離的實體並不是什麼大不了的事情,你可以很容易地將它附加回來,你知道的。實際上,如果我記得EJB3的行動的權利,JPA的設計方式是儘可能將實體附加在短的時間。再對其執行任何操作JPA前

只需merge(附回)你的實體:

em.merge(entity); 
1

一些原因是:

  1. 您在步驟2中使用@Remote EJB而不是@Local。
  2. 第一個EJB的事務上下文與第二個EJB的事務上下文不同。

容易理解的是,一旦事務關閉(落實或回滾),實體就會變得相互聯繫。

我沒有使用JSF的經驗,但我認爲一旦在JSF中調用ejb.getCategories(),EJB中的事務就完成了,因此實體就會脫節。你也沒有說明你是如何注入dbs的:我希望你用@EJB這樣做了。另外我讀過(至少@ManagedBean -annated)JSF不是(默認的?)事務。

+0

謝謝您的回答。我沒有使用@Remote EJB。 – Lester

1

可能發生這種情況的原因是,當您調用getCategories時,由於沒有事務而啓動新的事務。當函數退出時,事務完成並且所有實體都被分離。確保你在一次交易中完成所有步驟。

相關問題