【问题标题】:Is this correct approach of singleton SessionFactory?这是单例 SessionFactory 的正确方法吗?
【发布时间】:2020-01-17 11:25:11
【问题描述】:

我正在使用 Hibernate 而没有 @annotations

我试过这个代码:

    public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    private static StandardServiceRegistryBuilder builder;

    static {
        try {
            Configuration configuration = new Configuration().configure();
            configuration.configure("hibernate.cfg.xml");
            builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(builder.build());
        } catch (HibernateException ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

客户端代码:

    public static void main (String[] args) {                                         
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    List<Customer> customers = criteria.list();
    for (Customer customer : customers) {
        //print values
    }
    session.getTransaction().commit();
    session.close();
}

这也是我想知道的重要事情
如果我要在 Client class 中创建 HibernateUtil 类对象怎么办?

HibernateUtil hibernateUtil = new HibernateUtil();

【问题讨论】:

    标签: java hibernate singleton sessionfactory


    【解决方案1】:

    你可以参考stackoverflow链接: What are the advantages and disadvantages of creating an Object in static block in Java?.

    如果您希望在服务器或应用程序启动时创建 SessionFactory,则可以使用静态块。否则,请使用静态方法方法。你也可以使用枚举来创建单例。

    【讨论】:

    • 当你使用静态块时,这意味着在创建HibernateUtil实例之前静态块将被执行,这意味着你在HibernateUtil中的SessionFactory被创建并通过getSessionFactory()静态方法提供服务。这是对象的早期实例化。在这种情况下,您不必为 HibernateUtil 创建对象。直接调用 HibernateUtil 类的静态方法,获取 SessionFactory 的实例。
    • 我用过这个public class SingltoneHiber extends javax.swing.JFrame { private SessionFactory sessionFactory; public SingltoneHiber() { this.sessionFactory = HibernateUtil.getSessionFactory(); initComponents(); }
    【解决方案2】:

    所以,您有两个问题,一个是关于创建单例的正确方法,另一个是关于如果您在客户端创建 HibernateUtil 实例会发生什么。

    首先用于 HibernateUtil

    对于第二个问题,如果每个客户端都创建一个 HibernateUtil 类的实例,你就可以了,因为变量是静态的。如果一切按计划进行,将只有一个Hibernate SessionFactory 实例。

    至于你是否有正确的Hibernate SessionFactory 单例实现?这是一个更难回答的问题。虽然您的代码看起来不错,但多个类加载器可能会导致单例的各种不可预知的问题。如果单独的类加载器创建一个实例,您可能会有多个单例实例,这是您要避免的悖论。

    EJB 和 Spring Singleton 帮助

    使用 EJB 规范,您可以将会话 bean 标记为单例。如果您使用的是符合 Java Web 配置文件的服务器,我会这样做。如果您使用的是 Spring Boot,请使用它们提供的单例工具。如果它是一个独立的应用程序,请留意特殊的、非单一的 SessionFactory 行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2012-04-26
      相关资源
      最近更新 更多