gpt4 book ai didi

java - Hibernate EntityManger 新实例在合并后不返回查找结果

转载 作者:行者123 更新时间:2023-11-30 10:43:03 25 4
gpt4 key购买 nike

我合并了一个新实例(它已保存到数据库中)然后我关闭了实体管理器,打开了一个新实例试图找到该实体但返回了 null。

 public <T> T merge(Object source, Event<EntitiesPersistenceEventObject<T>> event, T t, boolean notifyGenericListeners) throws PersistenceException {
EntityManager entityManager = createEntityManager();

Object id = null;

PersistenceEventType eventType;

if (id == null || (id instanceof Number && ((Number) id).equals(0))) {
eventType = PersistenceEventType.ADDED_ENTITIES;
} else {
eventType = PersistenceEventType.UPDATED_ENTITIES;
}

try {
beginTransaction(entityManager);

t = entityManager.merge(t);
id = factory.getPersistenceUnitUtil().getIdentifier(t);

commitTransaction(entityManager);
//entityManager.refresh(t);
notifyListeners(event, source, eventType, notifyGenericListeners, t);

} catch (Exception ex) {
if (entityManager != null && entityManager.isOpen()) {
// entityManager.close();
}
throw new PersistenceException(ex);
} finally {
entityManager.close();
}
closeEntityManager();

return (T) find(t.getClass(), id);
}

查找函数:

public <T> T find(Class<T> type, Object id) {
EntityManager entityManager = getEntityManager();
try {
Map<String, Object> props = new HashMap<String, Object>();
props.put("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);
//query.setHint("javax.persistence.cache.retrieveMode", "BYPASS");
T t = entityManager.find(type, id);
//entityManager.refresh(t);
return t;
} catch (Exception e) {
e.printStackTrace();
System.out.println("find exception type: " + type + " id=" + id);
throw e;
} finally {
// entityManager.close();
}
}

getEntityManger 直接调用这个函数:

public synchronized static EntityManager getThreadEntityManager() {
//entityMangersPoolCounter = entityMangersPoolCounter % ENTITY_MANGERS_POOL_MAX_COUNT;
EntityManager em = threadLocal.get();
if (em == null || !em.isOpen()) {
factory.getCache().evictAll();
em = factory.createEntityManager();
System.out.println("Hooooooory, creating new EnTITY manager!..." + em.hashCode());

em.
setProperty("javax.persistence.sharedCache.mode", SharedCacheMode.NONE);
em.
setProperty("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH);
em.
setProperty("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);
em.
setProperty("javax.persistence.FlushModeType", FlushModeType.AUTO);
threadLocal.set(em);

}
return em;
}

closeEntityManger 只是关闭 threadEntityManger。

当调试合并函数时,会生成一个新的 id 并将其保存在数据库中,但是当在合并函数的最后一行调用“find”时,它会返回 null,自从我关闭合并中的旧线程 Entitymanger。在调试 AbstractEntityMnagerImpl i 时

CacheMode cacheMode = determineAppropriateLocalCacheMode( properties );

正在返回缓存模式 REFRESH。

Hibernate entityManger 版本 4.2.6.FinalHibernate 核心 4.2.5.Final

此外,我在 hibernate 中启用了 showsql 选项,它在执行 find 时显示了 select 语句,但仍然返回 null。

是我做错了什么,还是 hibernate 中的错误?

编辑:当我在服务器上执行生成的 sql 查询时,进一步调试 hibernate 正在生成良好的 sql,它返回代表实体的一行,但在 hibernate 中仍然返回空集!是否有任何 mysql 缓存来自 java 的连接?

EDIT2:跟踪日志 http://pastebin.com/BaKzvuW3 (与将查询放入 phpmyadmin 时相同(例如)我得到一行结果。

EDIT3:很明显,从 mysql 返回的结果是旧数据。即使我正在关闭实体管理器,提交更新/插入事务,即使我尝试在读取之前关闭事务(在提交旧事务后开始新事务)。

最佳答案

看来是mysql隔离和一致性的问题,好像调用

entityManager.getTransaction().commit();

不一定向 mysql 发送提交声明,或者它确实发送了,这是一个 mysql 错误。

将连接隔离配置为低于“可重复读取”的级别,解决了这个问题:

        cfg.setProperty("hibernate.connection.isolation", String.valueOf(Connection.TRANSACTION_READ_COMMITTED));

关于java - Hibernate EntityManger 新实例在合并后不返回查找结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37904772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com