Hibernate 只允许在我的 DAO 类中查询一次

Posted

技术标签:

【中文标题】Hibernate 只允许在我的 DAO 类中查询一次【英文标题】:Hibernate allows query only once in my DAO class 【发布时间】:2014-06-07 23:53:54 【问题描述】:

我试图编写一个 DAO 类来验证用户在网页上的登录,但是,Hibernate 查询似乎只工作一次。当用户第二次尝试登录时,Hibernate 会抛出很多错误:

public boolean isUserAndPasswordValid(String username, String password)
    
        User user = null;
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = session.beginTransaction();

    Query query = session.createQuery("from User where username = :username");
    query.setParameter("username", username);

    user = (User) query.uniqueResult();
//        List<?> list = query.list();
        tx.commit();

//        if (list.size() == 0)
//            return false;

//        user = (User) list.get(0);

    HibernateUtil.closeSessionFactory();

    if (user != null)
    
        if (user.getPassword().equals(User.md5Spring(password)))
            return true;
    
    return false;

由于我是休眠查询语言的新手,我不确定我是否正确执行查询。你们中的一些人能指出我哪里可能错了吗?另外,关于从 SessionFactory 返回的 Session,为什么我不能只执行以下操作?因为这对我来说似乎很直观(在实体表“用户”中搜索“用户名”?)

user = (User) session.get(User.class, username);

以下是尝试第二次登录时的错误消息:(顺便说一句,我正在使用 Ninja 框架和 Hibernate)

17:38:11.803 [qtp362239120-16] ERROR ninja.NinjaImpl - Emitting bad request 400. Something really wrong when calling route: /admin/loginPost (class: class controllers.AdministrationController method: public ninja.Result controllers.AdministrationController.loginPost(ninja.Context,models.User))
org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:201) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.internal.AbstractSessionImpl.getJdbcConnectionAccess(AbstractSessionImpl.java:341) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.<init>(JdbcCoordinatorImpl.java:114) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.<init>(TransactionCoordinatorImpl.java:89) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:258) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1589) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.context.internal.ThreadLocalSessionContext.buildOrObtainSession(ThreadLocalSessionContext.java:157) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.context.internal.ThreadLocalSessionContext.currentSession(ThreadLocalSessionContext.java:109) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
    at dao.UserDao.isUserAndPasswordValid(UserDao.java:27) ~[classes/:na]
    at controllers.AdministrationController.loginPost(AdministrationController.java:37) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]
    at ninja.params.ControllerMethodInvoker.invoke(ControllerMethodInvoker.java:55) ~[ninja-core-3.1.5.jar:na]
    at ninja.FilterChainEnd.next(FilterChainEnd.java:48) ~[ninja-core-3.1.5.jar:na]
    at ninja.NinjaImpl.invoke(NinjaImpl.java:112) ~[ninja-core-3.1.5.jar:na]
    at ninja.servlet.NinjaServletDispatcher.service(NinjaServletDispatcher.java:83) [ninja-servlet-3.1.5.jar:na]
    at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263) [guice-servlet-3.0.jar:na]
    at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178) [guice-servlet-3.0.jar:na]
    at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91) [guice-servlet-3.0.jar:na]
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62) [guice-servlet-3.0.jar:na]
    at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118) [guice-servlet-3.0.jar:na]
    at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113) [guice-servlet-3.0.jar:na]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1615) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1112) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:479) [jetty-servlet-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1046) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.Server.handle(Server.java:459) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:281) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232) [jetty-server-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505) [jetty-io-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) [jetty-util-9.1.2.v20140210.jar:9.1.2.v20140210]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]

【问题讨论】:

【参考方案1】:

构建 HibernateSessionFactory 的成本很高。它应该只在您的应用程序开始时完成一次。并作为服务器或应用程序关闭的一部分关闭。

应为每个请求创建和关闭会话对象。而且对于只读查询也不需要成为事务的一部分。因此,您可以删除事务开始和提交行和 closeSessionFactory 行并尝试。

因此,如果您注释 HibernateUtil.closeSessionFactory() 行,它将正常工作。

【讨论】:

以上是关于Hibernate 只允许在我的 DAO 类中查询一次的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate在超类中定义@Where注解

hibernate dao 设计问题

如何使用 Hibernate 5 正确创建 JPQL 查询(不推荐使用查询类型)

在ssh框架中的dao类中如何获取hibernate中的session

Struts + Hibernate:@SessionTarget 不工作

NewbieQuestion:我能以某种方式从 DAO 向 Spring+Hibernate 传递参数吗?