Java 休眠会话工厂

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19346585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:19:28  来源:igfitidea点击:

Hibernate Session Factory

javamysqlhibernatejakarta-eehibernate-session

提问by Lilit Mkrtchyan

In our web application we have a HibernateSessionFactoryclass, that is opening and closing connections. 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?

在我们的 Web 应用程序中,我们有一个HibernateSessionFactory类,用于打开和关闭连接。一切正常,但是当我们更新数据库中的数据时,它不会在我们的应用程序中发生变化。不幸的是,我们看到了数据库中的旧数据。我该如何解决?

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

}

回答by LMG

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 NOTconcerning 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:

我认为这个问题是不是涉及到数据库的连接,而是你如何保存和retrive数据。我会尝试更好地解释我自己:当您查询数据库以保存数据时,您执行以下步骤:

  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
  1. 公开会议
  2. 公开交易
  3. 构建对象
  4. 在会话中刷新并保存对象
  5. 提交事务
  6. 关闭交易
  7. 闭会

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
  1. 公开会议
  2. 公开交易
  3. 构建查询/条件
  4. 通过会话执行查询
  5. 关闭交易
  6. 闭会

If you don't follow this steps is possible that you have staledata 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.

如果您想进一步调查,您可以通过休眠暂停缓存的使用,您可以通过以下方式进行,但请记住,如果缓存数据是有原因的;) 这可以用作快速测试以便继续在发现错误是否是由于错误的查询使用引起的。

You should add this to your hibernate config xml

您应该将此添加到您的休眠配置 xml

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