【发布时间】:2016-06-19 07:05:00
【问题描述】:
我合并了一个新实例(它已保存到数据库中)然后我关闭了实体管理器,打开了一个新实例试图找到实体但返回 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.Final Hibernate核心4.2.5.Final
另外,我在 hibernate 中启用了 showsql 选项,它在执行 find 时显示 select 语句,但仍然返回 null。
是我做错了什么,还是休眠中的错误?
编辑:当我在服务器上执行生成的sql查询时,进一步调试hibernate正在生成好的sql,它返回代表实体的一行,但在hibernate中仍然返回空集!是否有任何 mysql 缓存用于来自 java 的连接?
EDIT2:跟踪日志http://pastebin.com/BaKzvuW3(将查询放入phpmyadmin时相同(例如)我得到一行结果。
EDIT3:现在很清楚,从 mysql 返回的结果是旧数据。即使我正在关闭实体管理器,提交更新/插入事务,即使我尝试在读取之前关闭事务(在提交旧事务后启动新事务)。
【问题讨论】: