【问题标题】:EntityManagerFactory is closed, HibernateEntityManagerFactory 已关闭,休眠
【发布时间】:2017-06-23 06:46:21
【问题描述】:

我最近创建了一个 Web 服务,它使用 Java 中的静态方法从数据库中获取项目列表。

Web 服务完美运行并将 JSON 返回给调用者。但是,它只工作一次。如果您尝试刷新或提出新请求,我会收到 EntityManagerFactory is closed 错误。

Web Service 类如下所示:

public class WebService extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    //obtain the list of vehicles from the database
        List<Vehicle> vehicles = ExecuteVehicle.getVehicleList();

        //create the Gson object and generate the Json
        Gson gson = new Gson();
        JsonElement element = gson.toJsonTree(vehicles, new TypeToken<List<Vehicle>>(){}.getType());

        //send the list of vehicles
        JsonArray jsonArray = element.getAsJsonArray();
        resp.setContentType("application/json");
        resp.getWriter().print(jsonArray);
    }
}

如您所见,车辆列表正在使用ExecuteVehicle.getVehicleList() 方法填充。

该方法如下所示:

public static List<Vehicle> getVehicleList(){

    //open a Session
    Session session = HibernateUtilities.getSessionFactory().openSession();

    //start a transaction
    session.beginTransaction();

    //SELECT STATEMENT for the entire list of Vehicles
    Query<Vehicle> query = session.getNamedQuery("SelectAllVehicles"); //query name is declared in the mapping file
    List<Vehicle> vehicles = query.list();

    //commit the changes and end the transaction
    session.getTransaction().commit();

    //close the Session
    session.close();

    //close the SessionFactory
    HibernateUtilities.getSessionFactory().close();

    return vehicles;
}

这是处理 Session 等的 HibernateUtilities 类:

public class HibernateUtilities {
    private static SessionFactory sessionFactory;
    private static StandardServiceRegistry standardServiceRegistry;

    static{
        try {
            //configure and build the service registry
            standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();

            //create the metadata
            Metadata metadata = new MetadataSources(standardServiceRegistry).getMetadataBuilder().build();

            //build the SessionFactory
            sessionFactory = metadata.getSessionFactoryBuilder().build();
        } catch (HibernateException e) {
            //in case the SessionFactory cannot be built, then the stackTrace is displayed
            e.printStackTrace();        
        }
    }

    //method that returns the Hibernate session factory
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
}

我的问题是 - 我怎样才能避免 EntityManagerFactory is closed 错误。此外,我将不得不一次又一次地实时获取此列表。这对 Hibernate 可行吗?以实时方式(例如,每 2 秒左右)从数据库中获取项目列表?我知道这取决于项目的数量等等,但我从技术的角度问 - 据我了解,打开和关闭 Session 需要很长时间 - 我可以在同一个 Session 中一遍又一遍地这样做吗如果有,怎么做?

【问题讨论】:

    标签: java hibernate web-services jpa entitymanager


    【解决方案1】:

    我会说你在那里做的太多了。

    您必须在使用工厂的openSession() 方法时刷新/提交事务并关闭会话。

    但我认为您不需要关闭 SessionFactory 本身

    //close the SessionFactory
    HibernateUtilities.getSessionFactory().close();
    

    去掉这条线,你就可以多次使用工厂了。

    【讨论】:

    • 看来你是完全正确的。有趣的是,我过去曾尝试过,但没有成功。有可能我还删除了(注释掉)session.close(); 代码行。我在 Hibernate 中几乎是一个完整的初学者,并且不知道所有这些东西到底是做什么的,我唯一能做的就是“猜测”或在教程中搜索它们究竟做了什么。无论如何,它现在似乎工作了!非常感谢!
    • 顺便问一下,是否有任何“危险”让 SessionFactory 保持打开状态?我应该以任何方式担心吗?
    • 在我使用过的所有应用程序中,SessionFActory 在启动期间创建了一次,并且仅在应用程序关闭时才被销毁。创建工厂是一个非常密集的过程,一旦它完成被创造了,我会不管它。您必须关闭会话,因为它们是有状态的,但工厂是无状态的,因此不需要根据请求重新创建。
    • 你打开了会话..但你最后关闭了工厂..当工厂关闭时你不能再创建任何会话
    • 欢迎。很高兴我能帮忙
    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 2017-08-05
    • 1970-01-01
    相关资源
    最近更新 更多