简体   繁体   English

Hibernate Session Factory

[英]Hibernate Session Factory

In our web application we have a HibernateSessionFactory class, that is opening and closing connections. 在我们的Web应用程序中,我们有一个HibernateSessionFactory类,即打开和关闭连接。 Everything is okay, but when we are updating data in the database, it doesn't change in our application. 一切都很好,但是当我们更新数据库中的数据时,它在我们的应用程序中不会改变。 Unfortunately, we see old data from the database. 不幸的是,我们从数据库中看到旧数据。 How can I fix it? 我该如何解决?

public class HibernateSessionFactory {

    private static final ThreadLocal threadLocal = new ThreadLocal();
    private static org.hibernate.SessionFactory sessionFactory;

    private static Configuration configuration = new Configuration();
    private static ServiceRegistry serviceRegistry; 

    private static final Logger log = Logger.getLogger(HibernateSessionFactory.class);

    static {
        try {
            configuration.configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
            . buildServiceRegistry();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Exception e) {
            log.error("Error Creating SessionFactory",e);

        }
    }

    private HibernateSessionFactory() {
    }

    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get(); 
        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession()
            : null;

            threadLocal.set(session);
        }
        return session;
    }

    public static void rebuildSessionFactory() {

        try {
            configuration.configure();
            serviceRegistry = new ServiceRegistryBuilder(). applySettings(configuration.getProperties()) 
            .buildServiceRegistry();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Exception e) {
            log.error("Error Creating SessionFactory",e);
        }
    }

    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);
        if (session != null) {
            session.flush();
            session.close();

        }
    }

    public static org.hibernate.SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static Configuration getConfiguration() {
        return configuration;
    }

}

Hibernate is a sofisticated and complex framework for building a layer between your program and the database, providing an object oriented model to help object oriented programs in their job. Hibernate是一个软化且复杂的框架,用于在程序和数据库之间构建一个层,提供面向对象的模型来帮助面向对象的程序。

In order to do this, and to be more performat of course, it creates a cache which stores somehow some of the data coming from the database, or going to the database. 为了做到这一点,并且当然是更好的格式,它创建了一个缓存,以某种方式存储来自数据库或转发到数据库的一些数据。

I think that this problem is NOT concerning the connection to the database but rather how you save and retrive data. 我认为这个问题不是关于与数据库的连接,而是关于如何保存和检索数据。 I'll try to explain my self better: when you query database to save data you do the following steps: 我将尝试更好地解释自己:当您查询数据库以保存数据时,您执行以下步骤:

  1. open session 公开会议
  2. open transaction 开放交易
  3. build object 构建对象
  4. flush and save object in session 在会话中刷新并保存对象
  5. commit transaction 提交事务
  6. close transaction 关闭交易
  7. close session 关闭会议

eg 例如

public Boolean saveNewCliente(Cliente c) {
    Session s = getSession();
    Transaction t = null;
    try {
        t = s.beginTransaction();
        s.save(c);
        s.flush();
        t.commit();
        s.close();
        return true;
    } catch (Exception e) {
         if (t!=null) t.rollback();
        System.out.println(e.getMessage());
        return false;
    }
    finally{
        s.close();
    }

}

A common pitfall happens when you query database to fetch data, is to leave the part relating the transaction out of your "query" steps. 当您查询数据库以获取数据时,会发生一个常见的陷阱,就是将与事务相关的部分保留在“查询”步骤之外。 As well for saving data you have to 同样需要保存数据

  1. open session 公开会议
  2. open transaction 开放交易
  3. build query / criteria 构建查询/标准
  4. execute query over session 执行会话查询
  5. close transaction 关闭交易
  6. close session 关闭会议

If you don't follow this steps is possible that you have stale data in your application, but not in your database. 如果不遵循此步骤,则可能是应用程序中存在过时数据,但数据库中没有。 A check may be to execute your update/save-query and check manually in the database if the data has changed/created. 检查可以是执行更新/保存查询,如果数据已更改/创建,则在数据库中手动检查。 If your application then loads stale data you know you do the fetch-query in the wrong way(without using transaction). 如果您的应用程序然后加载陈旧数据,您知道您以错误的方式执行获取查询(不使用事务)。 Here's a snipped of example 这是一个例子

    public Cliente get(Integer id) {
    Session s = getSession();
    Transaction tx = s.beginTransaction();
    try {
        System.out.println("get cliente by id");
        Cliente res = new Cliente();
        res = (Cliente) s.get(Cliente.class, id);
        tx.commit();
        return res;
    } catch (Exception e) {
        tx.rollback();
        System.out.println(e.getMessage());
        return null;
    }finally{
        s.close();
    }
}

If you want to furthermore investigate you can suspend the usage of cache by hibernate, you can do it in the following way, but remember that if data is cached there is a reason ;) This can be useful as a quick test in order to proceed in discovering if the error is due to wrong query usage. 如果你想进一步研究你可以通过hibernate暂停缓存的使用,你可以通过以下方式完成它,但请记住,如果数据被缓存,则有一个原因;)这可以作为快速测试以便继续在发现错误是否是由于错误的查询使用。

You should add this to your hibernate config xml 你应该将它添加到你的hibernate config xml中

<!-- to disable cache -->
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM