【问题标题】:Hibernate issue with `SessionFactory``SessionFactory` 的休眠问题
【发布时间】:2015-06-10 12:30:01
【问题描述】:

我有一个使用 Hibernate 的 JSP、Servlet(纯 JSP、Servlet)应用程序。下面是一个表的Hibernate 实现类。

DesignationImpl.java

package dao;

import model.sub.DesigAllBean;
import java.util.List;
import model.main.Designation;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

/**
 *
 * @author Yohan
 */
public class DesignationImpl implements DesignationInterface
{


    @Override
    public Session openCurrentSession() {
            Session currentSession = getSessionFactory().openSession();
            return currentSession;
    }

    @Override
    public Transaction openTransaction(Session session) {
        Transaction beginTransaction = session.beginTransaction();
        return beginTransaction;
    }

    private static SessionFactory getSessionFactory() {

        Configuration configuration = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                        .applySettings(configuration.getProperties());
        SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
        return sessionFactory;
    }

    @Override
    public void save(Designation d, Session session)
    {
        session.save(d);
    }

    @Override
    public void update(Designation d, Session session) 
    {
        session.update(d);
    }
}

下面是调用上述类的服务类。

DesignationService .java

package service;

import dao.Common;
import model.sub.*;
import dao.DesignationImpl;
import dao.DesignationInterface;
import java.util.ArrayList;
import java.util.List;
import model.main.Designation;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author Yohan
 */
public class DesignationService 
{
    private DesignationInterface designationInterface;

    public DesignationService()
    {
        designationInterface = new DesignationImpl();
    }

    public Session getSession()
    {
        Session session = designationInterface.openCurrentSession();
        return session;
    }

    public Transaction getTransaction(Session session)
    {
        return designationInterface.openTransaction(session);
    }

    public String save(Designation d)
    {
        Session session = designationInterface.openCurrentSession();
        Transaction transaction = null;
        String result="";

        try
        {
            transaction = designationInterface.openTransaction(session);
            designationInterface.save(d,session);
            transaction.commit();
            result = Common.SAVE_SUCCESS;
        }
        catch(Exception e)
        {
            e.printStackTrace();

            if(transaction!=null)
            {
                transaction.rollback();
            }
            result = Common.SAVE_ROLLBACK;
        }
        finally
        {
            session.close();
        }

        return result;
    }

    public String update(Designation d)
    {
        Session session = designationInterface.openCurrentSession();
        Transaction transaction = null;
        String result="";

        try
        {
            transaction = designationInterface.openTransaction(session);
            designationInterface.update(d,session);
            transaction.commit();
            result = Common.SAVE_SUCCESS;
        }
        catch(Exception e)
        {
            e.printStackTrace();

            if(transaction!=null)
            {
                transaction.rollback();
            }
            result = Common.SAVE_ROLLBACK;
        }
        finally
        {
            session.close();
        }

        return result;
    }
}

servlet 像下面这样调用它们。

DesignationService desigSrvc=new DesignationService();

        Designation designation=desigSrvc.findByForiegnKey(idEmployee);

        Employee empl=new Employee();
        empl.setIdEmployee(idEmployee);

        if(designation.getDateCreated()==null)
        {
            designation.setDateCreated(Common.getCurrentDateSQL());
        }   

        designation.setEmployee(empl);
        designation.setDesignation(txtDesignation);
        designation.setLocation(location);
        designation.setSalary(salary);
        designation.setDatePromoted(datePromoted);
        designation.setLastUpdated(Common.getCurrentDateSQL());       

        desigSrvc.save(designation);

如您所见,那里发生了一件坏事,即 servlet 每次执行时都会创建新的SessionFactory 实例。我遇到了Driver#Connect 问题,我想这可能是它的原因.

我阅读了 stackoverflow 帖子,有些帖子似乎建议在整个应用程序中只使用一个 SessionFactory。如果合适,那我该怎么做?也许制作一个像下面这样的单例类并在我的实现类中使用它?

public class SessionFactoryBuilder
{
    private static SessionFactoryBuilder instance;
    private static SessionFactory sessionFactory;

    private SessionFactoryBuilder()
    {
    }

    private static void buildConfig()
    {
        Configuration configuration = new Configuration().configure();
            StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                            .applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(builder.build());
    }

    public static SessionFactoryBuilder getInstance()
    {
         if(instance == null) 
         {
            instance = new SessionFactoryBuilder();
            buildConfig();
         }
      return instance;
    }

    public SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }
}

那么线程呢? Servlet 不是多线程的吗?

【问题讨论】:

  • 你的 DesignationInterface 在哪里??
  • 您好,您需要构建一个单例 sessionfactory 提供程序类..我认为它应该可以解决您的问题..

标签: java multithreading hibernate servlets sessionfactory


【解决方案1】:

我更正了 Viraj Nalawade 的代码,其中有一些错误:

class HibernateUtil {
    private static SessionFactory INSTANCE = null;

    public static SessionFactory getSessionFactory() {
        if (INSTANCE == null) {
            createSessionFactory();
        }
        return INSTANCE;
    }

    private synchronized static void createSessionFactory() {
        if (INSTANCE != null) {
            return;
        }
        Configuration configuration = new Configuration();
        configuration.configure();
        ServiceRegistry serviceRegistry = configuration.getStandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        INSTANCE = configuration.buildSessionFactory(serviceRegistry);
    }
}

【讨论】:

    【解决方案2】:

    正如我所评论的,我将 HibernateUtil.java 类作为 Singleton。此类可以使用 HibernateUtil.getSessionFactory() 为您提供会话工厂,您应该从您的 DesignationImpl 类中删除相关代码

    public class HibernateUtil {
    
    private static StandardServiceRegistry serviceRegistry; 
    private static SessionFactory INSTANCE = null;
    public static SessionFactory getSessionFactory() {
         if(INSTANCE=null){
              createSessionFactory():
          }
          return sessionFactory;
    }
    private synchronized static void createSessionFactory(){
        if(INSTANCE!=null){return;}
        Configuration configuration = new Configuration();
        configuration.configure();
        SeviceRegistry=newStandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        }
      }
    }
    

    找到上面的代码,请提出建议/评论以确认代码的正确性。我认为使用这个会处理线程。我添加了双重检查以避免多个会话工厂创建广告它是一个沉重的资源。

    【讨论】:

    • 我也发布了我的单身课程。案例是线程问题。我听说SessionFactory 无论如何都是线程安全的。
    • DesignationImpl 类是在说什么..?我不认为它是 SingleTon ..我认为它会在您每次调用 getSessionFactory() 时创建 sessionfactory ..请您帮我或纠正我..
    • 我说的是SessionFactoryBuilder类。在我的问题中,我提到我也创建了它,即使我不使用它。
    • 哦,我找不到任何用法,所以我忽略了它。是的,SessionFactory 是线程安全的。。
    • @JustCause 然后你使用这个 SessionFactoryBuilder 类,你的问题可能会得到解决......我认为它很好......只是如果我们将 SessionFactoryBuilder .getSessionFactory 方法设为静态并添加一个会更好对 SessionFactoryBuilder.sessionFactory 进行空检查...休息看起来很棒..!!:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2012-01-23
    • 2016-03-21
    • 2013-06-11
    • 2012-09-18
    • 2014-01-10
    相关资源
    最近更新 更多