Hibernate Session 空指针异常

Hibernate Session null-pointer exception

我被这个问题困扰了好几天无法弄清楚,我的意思是我知道 sessionFactory 必须为空,正如堆栈跟踪指示的那样,但我不明白为什么?异常总是回到行:

Session session = hibernateUtil.getSessionFactory().getCurrentSession();

这是堆栈跟踪的修剪版本:

DEBUG - Creating new transaction with name [com.sga.app.dao.DisplayStatsDAO$$EnhancerBySpringCGLIB$$f03b1e71.getForename]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG - Acquired Connection [jdbc:oracle:thin:system/system@localhost:1521/XE, UserName=SYSTEM, Oracle JDBC driver] for JDBC transaction
DEBUG - Switching JDBC Connection [jdbc:oracle:thin:system/system@localhost:1521/XE, UserName=SYSTEM, Oracle JDBC driver] to manual commit
DEBUG - Returning cached instance of singleton bean 'sessionFactory'
DEBUG - Initiating transaction rollback
DEBUG - Rolling back JDBC transaction on Connection [jdbc:oracle:thin:system/system@localhost:1521/XE, UserName=SYSTEM, Oracle JDBC driver]
DEBUG - Releasing JDBC Connection [jdbc:oracle:thin:system/system@localhost:1521/XE, UserName=SYSTEM, Oracle JDBC driver] after transaction
DEBUG - Returning JDBC Connection to DataSource
DEBUG - Invoking afterPropertiesSet() on bean with name 'error'
DEBUG - Rendering view [org.springframework.web.servlet.view.JstlView: name 'error'; URL [/WEB-INF/jsps/error.jsp]] in DispatcherServlet with name 'dispatcher'
DEBUG - Added model object 'userBean' of type [com.sga.app.beans.UserBean] to request in view with name 'error'
DEBUG - Added model object 'org.springframework.validation.BindingResult.userBean' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'error'
DEBUG - Added model object 'displayStatsDAO' of type [com.sga.app.dao.DisplayStatsDAO] to request in view with name 'error'
DEBUG - Added model object 'org.springframework.validation.BindingResult.displayStatsDAO' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'error'
DEBUG - Added model object 'username' of type [java.lang.String] to request in view with name 'error'
DEBUG - Forwarding to resource [/WEB-INF/jsps/error.jsp] in InternalResourceView 'error'
java.lang.NullPointerException
    at com.sga.app.dao.DisplayStatsDAO.getForename(DisplayStatsDAO.java:66)
    at com.sga.app.dao.DisplayStatsDAO$$FastClassBySpringCGLIB$d44a3e.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

还有我的 DAO:

package com.sga.app.dao;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sga.app.beans.UserBean;
import com.sga.app.hibernate.HibernateUtil;

@Component("displayStatsDAO")
@Repository
@Transactional
@Configuration
public class DisplayStatsDAO extends HttpServlet implements Serializable {

private static final long serialVersionUID = 1L;
public static final String TEST = "testing";
public String string = TEST;
public String example = "example String";
public String forename;
public Session session;
private HibernateUtil hibernateUtil;

@Bean
public DisplayStatsDAO displayStatsDAO() {
    return new DisplayStatsDAO();
}

public DisplayStatsDAO() {

}

@Transactional
public String getForename() {
    @SuppressWarnings("rawtypes")
    ArrayList result = new ArrayList();
    String returnValue = "";
    Session session = hibernateUtil.getSessionFactory().getCurrentSession();
    if (session == null) {
        System.out.println("NULL SESSION");
    } else {
        try {
            session.beginTransaction();
            Authentication authentication = SecurityContextHolder
                    .getContext().getAuthentication();
            String userLoggedIn = authentication.getName();
            System.out.println("SESSION IS ACTIVE");
            System.out.println(userLoggedIn);
            Criteria criteria = session.createCriteria(UserBean.class);
            criteria.add(Restrictions.like("username", userLoggedIn));
            List<UserBean> user = (List<UserBean>) criteria.list();
            session.getTransaction().commit();
            for (UserBean userDetails : user) {
                result.add(userDetails.getForename());
                returnValue = userDetails.getForename().toString();
            }
        } catch (HibernateException e) {
            e.printStackTrace();
        }
        System.out.println("Return value is " + returnValue);
    }
    return returnValue;
}

public Session getSession() {
    return session;
}

public void setSession(Session session) {
    this.session = session;
}

public String getLoggedInUserName() {
    Authentication authentication = SecurityContextHolder.getContext()
            .getAuthentication();
    String userLoggedIn = authentication.getName();
    return userLoggedIn;
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    req.getRequestDispatcher("userstats.jsp").forward(req, resp);
}
}

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!-- Database connection settings -->
    <property name="hibernate.connection.driver_class">
        oracle.jdbc.OracleDriver
    </property>
    <property name="hibernate.connection.url">
        jdbc:oracle:thin:system/system@localhost:1521/XE
    </property>
    <property name="hibernate.connection.username">system</property>
    <property name="hibernate.connection.password">password</property>
    <!-- Oracle dialect declaration -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.Oracle10gDialect
    </property>
    <property name="show_sql">true</property>
    <mapping resource="com/sga/app/xml/sga.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>

HibernateUtil.java:

package com.sga.app.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {

private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;

public HibernateUtil() {
    sessionFactory = createSessionFactory();
}

public SessionFactory getSessionFactory() {
    return HibernateUtil.sessionFactory;
}

private static SessionFactory createSessionFactory() {

    Configuration configuration = new Configuration();
    configuration.configure("hibernate.cfg.xml");
    serviceRegistry = new ServiceRegistryBuilder().applySettings(
            configuration.getProperties()).buildServiceRegistry();
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    return sessionFactory;
}
}

Pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SgaWebApp</groupId>
<artifactId>SgaWebApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.0.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.2.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>3.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>3.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>3.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>4.1.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.1.4.Final</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
</dependencies>
</project>

app.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD   
3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sga.app.beans.UserBean" table="USERS">
    <id name="username" type="varchar">
        <column name="USERNAME"></column>
    </id>
    <property name="roundScore" type="int">
        <column name="ROUNDSCORE"></column>
    </property>
    <property name="fairways_hit" type="int">
        <column name="FAIRWAYS_HIT"></column>
    </property>
    <property name="gir" type="int">
        <column name="GIR"></column>
    </property>
    <property name="sand_saves" type="int">
        <column name="SAND_SAVES"></column>
    </property>
    <property name="putts" type="int">
        <column name="PUTTS"></column>
    </property>
</class>
</hibernate-mapping>

userstats.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="${pageContext.request.contextPath}/static/css/main.css"
rel="stylesheet" type="text/css">
<title>SGA-user stats</title>
</head>
<body>
</div>
<br />
<!-- Logout option -->
<div id="logoutOptionDiv" align="right">
    <a id="logoutOption" style="color: blue;"
        href='<c:url value="/j_spring_security_logout"></c:url>'>Logout</a>
</div>
<br />
<h2 class="displayStatsLeaderboardHeader">Your stats</h2>
<table class="displayStatsTable" border="1">
    <tr>
        <td>Username</td>
        <td>Forename</td>
        <td>Surname</td>
    </tr>
    <tr>
        <td class="displayStatsTableData">${stats}</td>
        <td class="displayStatsTableData">${stats.string}</td>
        <td class="displayStatsTableData">${stats.example}</td>
    </tr>
</table>
</body>
</html>

您的 hibernateUtil 字段为空。实际上,为什么要为此引入实例字段?没有向其中注入任何内容,您可以在此空字段上调用实例方法。将方法设为静态:

public static SessionFactory getSessionFactory() {
   return sessionFactory;
}

然后:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

试试这个:- 用这个替换你的 HibernateUtil class:-

import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.SessionFactory;

public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
        try {
           sessionFactory = new   AnnotationConfiguration().configure().buildSessionFactory(); 
        } catch (Throwable ex) {
          System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

你也应该试试

SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

Session session = sessionfactory.openSession();

而不是

Session session = hibernateUtil.getSessionFactory().getCurrentSession();

希望有用,

已更新

@Autowired
private HibernateUtil hibernateUtil;

当我改行时,空指针异常被根除:

Session session = hibernateUtil.getSessionFactory().getCurrentSession();

至:

session = HibernateUtil.createSessionFactory().openSession();

我认为问题是我最初试图获得一个当前已关闭的会话,但我本以为会收到我之前看到的 'session is closed!' 消息?不管怎样,空指针异常已经解决了。

(HibernateUtil 中的 createSessionFactory() 方法中的代码未更改)