Hibernate读取功能显示旧数据

Gor*_*ore 7 session caching hibernate

我在显示数据库中的数据时出现问题.如果我更新一个对象,有时我会得到旧数据,有时候是新数据.更新功能运行良好(我可以在DB中看到正确的更新),而read函数似乎获得缓存数据.我试图禁用两个缓存,尝试在更新/保存期间打开和关闭会话,但它仍然无法正常工作.User和Store bean都有Lazy提取.谢谢!

阅读功能:

    public static List<Store> getStoreByUser(User user)
        throws HibernateException {
    List<Store> result = null;
    Session session = sessionFactory.getCurrentSession();   
    Transaction transaction = null;
    try {
        transaction = session.getTransaction();
        Criteria criteria = session.createCriteria(Store.class);
        criteria.add(Restrictions.eq("userUserID", user));
        result = criteria.list();
    } catch (HibernateException he) {
        logger.error("No Store found for user: = " + user, he);
        throw he;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

更新/保存功能:

    public static Integer insertOrUpdateStore(Store store)
        throws HibernateException {
    Integer id = null;
    Session session = sessionFactory.getCurrentSession();   
    Transaction transaction = null;
    try {
                    transaction = session.getTransaction();
        if (store.getStoreID() != null && store.getStoreID() != 0) {

            session.merge(store);
            transaction.commit();

        } else {
                id = (Integer) session.save(store);
            transaction.commit();               
        }
    } catch (HibernateException he) {
        if (transaction != null) {
            transaction.rollback();
        }
    } finally {
    }       
    return id;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ger 5

通常,您具有"已提交读取" 的隔离级别.这使您的事务可以查看其他事务已提交的更改.隔离级别由底层dbms实现,而不是由hibernate实现.

您无法禁用第一级缓存(可能通过使用无状态会话,不应将其用于一般用途).执行查询时,NH始终在缓存中返回值,以确保在内存中不再获取相同的db记录.

如果这对您来说是个问题,则应切换到更高的隔离级别.例如,可重复读取(这意味着它所说的:当多次读取相同的数据时,总会得到相同的结果).仍有机会看到其他交易的变化.使用可序列化的隔离级别,您不应再遇到此类问题.

注意:切换到另一个隔离级别是大多数系统的重大变化,应该仔细规划.

  • 我不知道哪个是我的默认隔离值,但我已将其切换为"read committed",在hibernate.cfg.xml中添加:<property name ="hibernate.connection.isolation"> 2 </ property>有用!!我花了很多时间寻找解决方案; 你的解释很清楚!非常感谢Stefan! (4认同)

小智 5

我有同样的问题,我的查询 select * 返回旧数据。我在 hibernate.cfg.xml 文件中关闭了这样的二级缓存

<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.c3p0.max_statements">0</property>
Run Code Online (Sandbox Code Playgroud)

我会尝试在 transaction.commit() 之前/之后添加 session.flush() 或 session.clear() 但它没有给出积极的结果