Hibernate EntityManger新实例在合并后没有返回查找结果

时间:2016-06-19 07:05:00

标签: java hibernate

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

navigator.getUserMedia = ( navigator.getUserMedia ||
                       navigator.webkitGetUserMedia ||
                       navigator.mozGetUserMedia ||
                       navigator.msGetUserMedia);

查找功能:

 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);
}

getEntityManger直接调用此函数:

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();
    }
}

closeEntityManger只关闭threadEntityManger。

当对合并功能进行调试时,会生成一个新的id并将其保存在数据库中,但是当在合并函数的最后一行调用“find”时它返回null,它将在一个新的实体管理器上,因为我关闭了合并中的旧线程Entitymanger。 当debuging AbstractEntityMnagerImpl i

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;
}

返回缓存模式REFRESH。

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

另外,我在hibernate中启用了showsql选项,并在显示find时显示了select语句,但仍返回null。

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

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

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

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

1 个答案:

答案 0 :(得分:1)

看来这是mysql隔离和一致性的问题,似乎在调用

entityManager.getTransaction().commit();

不一定向mysql发送提交语句,或者它确实是mysql错误。

将连接隔离配置为低于“REPEATABLE READ”的级别,解决了以下问题:

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