2 回答

TA貢獻1871條經(jīng)驗 獲得超8個贊
您正在混合本機 SQL 和休眠。基本上,當您第一次檢索實體時,它會存儲在您的會話 EntityManager 中。然后您使用純 SQL 更新數(shù)據(jù)庫中的行,但就休眠而言,實體并沒有被弄臟,因為它不夠聰明,無法理解純 SQL 與對象模型的關(guān)系。當你第二次檢索它時,它只是給你它已經(jīng)緩存在 EntityManager 中的原始實體,而不是查詢數(shù)據(jù)庫。
解決方案是在更新后簡單地從 EntityManager 中手動強制驅(qū)逐實體,如下所示: sessionFactory.getCurrentSession().evict(entity);
或者您可以簡單地更新您獲取的實體并將其持久化(最佳解決方案恕我直言,沒有多余的 DAO 方法,以及遠離數(shù)據(jù)庫的最佳抽象):
ExampleEntity entity = (ExampleEntity) sessionFactory.getCurrentSession().createCriteria(ExampleEntity.class).add(Restrictions.eq("id", 190001L)).uniqueResult();
entity.setState(State.CLOSED);
entity.setVersion(e.getVersion() + 1);
sessionFactory.getCurrentSession().update(entity);
基本上...無論您選擇哪個選項,都不要在同一事務(wù)中混合使用純 SQL 和休眠查詢。一旦 hibernate 加載了一個對象,它將從其緩存中返回相同的實體,直到它知道它是臟的。當使用純 SQL 弄臟實體時,知道實體是臟的還不夠聰明。如果您別無選擇并且必須使用 SQL(在設(shè)計良好的休眠模型中永遠不會出現(xiàn)這種情況),則調(diào)用 evict 來告訴休眠實體是臟的。
添加回答
舉報