第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Hibernate 中同時使用 Query Api 和 Criteria Api 會導(dǎo)致問題

在 Hibernate 中同時使用 Query Api 和 Criteria Api 會導(dǎo)致問題

慕沐林林 2023-05-17 17:37:31
當我使用查詢 API 更新一行,然后在同一事務(wù)中使用標準 API 檢索數(shù)據(jù)時,我得到的是舊值,而不是更新后的值。為什么會這樣,我該如何解決這個問題?我需要獲取更新的值。@Service@Transactionalpublic class ExampleServiceImpl implements ExampleService {    @Autowired    ExampleRepository exampleRepository;    @Transactional    public void example() {        ExampleEntity entity = (ExampleEntity) sessionFactory.getCurrentSession().createCriteria(ExampleEntity.class).add(Restrictions.eq("id", 190001L)).uniqueResult();        exampleRepository.updateState(190001L, State.CLOSED);        ExampleEntity updatedEntity = (ExampleEntity)sessionFactory.getCurrentSession().createCriteria(ExampleEntity.class).add(Restrictions.eq("id", 190001L)).uniqueResult();        assertEquals(State.CLOSED, updatedEntity.getState());    }}@Repositorypublic class ExampleRepositoryImpl implements ExampleRepository {    public void updateState(Long id, State state) {        String updateScript = "update exampleEntity set state= '%s', " +                "VERSION = VERSION + 1 " +                "where ID = %s;";        updateScript = String.format(updateScript, state, id);        Query sqlQuery = sessionFactory.getCurrentSession().createSQLQuery(updateScript);        sqlQuery.executeUpdate();    }}注意:如果我刪除第一行并且沒有在開頭檢索實體,一切都會按我預(yù)期的那樣進行。
查看完整描述

2 回答

?
ITMISS

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 來告訴休眠實體是臟的。


查看完整回答
反對 回復(fù) 2023-05-17
?
米脂

TA貢獻1836條經(jīng)驗 獲得超3個贊

當您獲得結(jié)果時,您的交易仍未提交 - 這就是您獲得“舊”價值的原因。



查看完整回答
反對 回復(fù) 2023-05-17
  • 2 回答
  • 0 關(guān)注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號