2017-07-17 145 views
0

我有延長BaseRepository多個倉庫如下:更新查詢提交

public abstract class IsoRepository<T extends Serializable> { 
    @PersistenceContext 
    protected EntityManager entityManager; 

    public void persist(T obj) { 
     entityManager.persist(obj); 
    } 
} 

@Stateless 
public class T1Repository extends BaseRepository<T1> { 
    // methods depending on repository 
} 

@Stateless 
public class T2Repository extends BaseRepository<T2> { 
    public Optional<T2> findByOrderId(String id) { 
     return entityManager.createNamedQuery(/* ... */, T2.class) 
      .setParameter("id", id).getResultList().stream().findFirst(); 
    } 
} 

// and others 

EJB bean包含方法承擔一切節約交易:

@Stateless 
public class TransactionService { 
    @EJB 
    private T2Repository t2Repository; 

    public void saveTransaction() { 
     // Here occurs logic that saves new entities to database via repositories injected with EJB annotation 
     // and also as the last operation update is performed: 
     T2 t2 = t2Repository.findById(id); 
     t2.setProperty(someProperty); 
     t2Repository.persist(t2); 
    } 
} 

的問題是,所有插入查詢是保存在數據庫中,但不是這一個糟糕的更新。我發現我需要明確地調用entityManager.flush(),因爲它似乎解決了這個問題,但我不明白爲什麼會發生這種情況。我一直認爲在事務提交後,所有數據都會自動刷新。我有沒有改變配置中的東西?

+0

平齊()是在一個事務結束自動調用。你在一個事務中調用了t2Repository,並且你沒有自動刷新。 「我一直認爲,交易完成後,所有數據都會自動刷新」 - 你是對的。 – xyz

+0

但是不應該在方法'saveTransaction'完成後調用flush?因爲現在看起來好像不是(手動調用方法中的最後一個操作) – Fuv

+0

pls顯示persistence.xml文件以及如何配置事務 – xyz

回答

1

按照JPA-文檔

"persist(Object entity) 
Make an instance managed and persistent." 

手段,堅持只能用於插入件。通常你應該得到

"EntityExistsException - if the entity already exists. 
(If the entity already exists, the EntityExistsException may be 
thrown when the persist operation is invoked, or the 
EntityExistsException or another PersistenceException may be thrown at 
flush or commit time.)" 

作爲文檔狀態。因此:根據JPA定義,

T2 t2 = t2Repository.findById(id); 
    t2.setProperty(someProperty); 
    t2Repository.persist(t2); 

在任何情況下,都應立即或在事務結束時導致EntityExistsException。這一端也可以在本身調用TransactionService.persist的方法的末尾。 這個異常應該導致任何情況下的回滾,所以你的更新永遠不會完成。

我的建議:

擺脫持續通話,因爲對象變爲查找過程管理,改變將在交易結束時完成。

參見:does-jpa-hibernate-save-even-when-not-calling-persist

+0

您的回答使我走上了正確的軌道。我正在以這種方式更新兩個實體(查找,更改,堅持)。儘管我沒有得到任何異常(Hibernate忽略了這些情況),但是一定是錯誤的。這真的很奇怪,因爲一個實體被更新了,另一個沒有被更新,但是在刪除兩個堅持的陳述之後,一切似乎都像魅力一樣工作。謝謝! – Fuv