sessionFactory.getCurrentSession()导致NullPointerException

时间:2017-07-28 01:02:13

标签: java spring spring-framework-beans

当我将文件作为JUnit测试运行时,UsersDAOImpl类应该添加一个新用户,但是当我调用sessionFactory.getCurrentSession()并且我不知道原因时,我一直得到一个NullPointerException。

会话工厂放在beans.xml中。

出于显而易见的原因,删除了数据库的凭据。

[beans.xml文件]

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
        <!-- enable autowiring -->
        <context:component-scan base-package="src"></context:component-scan>
        <!-- enable @Transactional -->
        <tx:annotation-driven />
        <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
            <property name="username" value="{Master}"></property>
            <property name="password" value="{password}"></property>
            <property name="url" value="{url}"></property>
        </bean>
        <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="myDataSource"></property>
            <property name="packagesToScan" value="src"></property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
        </bean>
        <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="mySessionFactory">
    </property> 
                </bean>
        <bean id="usersDAO" class="dao.UsersDAOImpl">
            <property name="sessionFactory" ref="mySessionFactory">        </property>
        </bean>
     </beans>

[UsersDAOImpl.java]

package dao;

import static org.junit.Assert.*;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import customExceptions.*;
import util.Debug;
import util.HibernateUtil;
import domain.Users;
@Transactional
public class UsersDAOImpl implements UsersDAO {

@Autowired
private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionfactory) {
    this.sessionFactory = sessionfactory;
}

@Test
public void testPush() {
    try {
        push(new Users("username6", "email@gmail.com", "password", "firstName", "lastName", false));
    } catch (UserNameTakenException e) {
        e.printStackTrace();
        fail();
    } catch (InvalidNameException e) {
        e.printStackTrace();
        fail();
    }
}

/**
 * Adds a new user to the database
 * 
 * @param newUser
 *            The user to be added
 * @throws UserNameTakenException
 *             In the case a username is taken
 * @throws InvalidNameException
 *             If a field is left blank, but front end should prevent that
 */
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void push(Users newUser) throws UserNameTakenException, InvalidNameException {
    // For debugging purposes:
    Debug.printMessage(this.getClass(), "push()", "invoked");
    // Check if there are any empty Strings
    if (newUser.getUsername().isEmpty() || newUser.getPassword().isEmpty() || newUser.getFirstName().isEmpty()
            || newUser.getLastName().isEmpty()) {
        throw new InvalidNameException("There is an empty String");
    }




    // Get the session
    //THIS IS WHERE I GET THE EXCEPTION
    Session sess = sessionFactory.getCurrentSession();




    // Check to see if the username is taken
    Users users = getUserByName(newUser.getUsername());
    // If the list is not empty, a user with the name was found
    if (users != null) {
        sess.close();
        throw new UserNameTakenException("The username was found in the database");
    } else {
        // Otherwise, add the new user
        // Debug
        Debug.printMessage(this.getClass(), "push()", "username available.");
        Debug.printErrorMessage(this.getClass(), "push()", "saving " + newUser.getUsername());
        sess.save(newUser);
        sess.close();
    }

}

/**
 * Updates the User's password in the database
 * 
 * @param user
 *            The user to change
 * @param newVal
 *            The new password
 */
@Override
public void updatePassword(Users user, String newVal) {
    Debug.printMessage(this.getClass(), "updatePassword()", "invoked");
    Session sess = HibernateUtil.getSession();
    Transaction trans = sess.beginTransaction();
    user.setPassword(newVal);
    sess.update(user);
    trans.commit();
    sess.close();
}

/**
 * Updates the User's first name in the database
 * 
 * @param user
 *            The user to change
 * @param newVal
 *            The new first name
 */
@Override
public void updateFirstName(Users user, String newVal) {
    // For debugging purposes:
    Debug.printMessage(this.getClass(), "updateFirstName()", "invoked");
    Session sess = HibernateUtil.getSession();
    Transaction trans = sess.beginTransaction();
    user.setFirstName(newVal);
    sess.update(user);
    trans.commit();
    sess.close();
}

/**
 * Updates the User's last name in the database
 * 
 * @param user
 *            The user to change
 * @param newVal
 *            The new last name
 */
@Override
public void updateLastName(Users user, String newVal) {
    // For debugging purposes:
    Debug.printMessage(this.getClass(), "updateLastName()", "invoked");
    Session sess = HibernateUtil.getSession();
    Transaction trans = sess.beginTransaction();
    user.setLastName(newVal);
    sess.update(user);
    trans.commit();
    sess.close();
}

/**
 * Returns the user with the given username
 * 
 * @param username
 *            The username to find
 */
@Override
public Users getUserByName(String username) {
    // For debugging purposes:
    Debug.printMessage(this.getClass(), "getUserByName()", "invoked");
    Session sess = HibernateUtil.getSession();
    Users user = (Users) sess.get(Users.class, username);
    sess.close();
    return user;
}

/**
 * Returns a list of all users from A_USERS
 */
@Override
public List<Users> getAllUsers() {
    // For debugging purposes:
    Debug.printMessage(this.getClass(), "getAllUsers()", "invoked");
    Session sess = HibernateUtil.getSession();
    Query query = sess.getNamedQuery("getAllUsers");
    List<Users> users = query.list();
    sess.close();
    return users;
 }
}

另外,如果格式不正确,我道歉。这是我第一次发帖提问。

堆栈跟踪

java.lang.NullPointerException
at dao.UsersDAOImpl.push(UsersDAOImpl.java:65)
at dao.UsersDAOImpl.testPush(UsersDAOImpl.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

2 个答案:

答案 0 :(得分:0)

sessionFactory字段为空。

至于为什么,我只能猜测。您既可以自动连接sessionFactory字段,也可以通过applicationContext.xml中的配置将其作为属性注入。做一个或另一个,而不是两个,看看会发生什么。

答案 1 :(得分:-1)

首次调用getCurrentSession()时会打开会话,并在事务结束时关闭会话。如果一个会话不存在,则会创建一个全新的会话,如果已存在,则会使用现有会话。它自动配置自动刷新和自动关闭属性为true表示会话将自动刷新和关闭。

当我们的事务运行很长时间时,我们可以使用getCurrentSession()方法。要使用此方法,我们需要在hibernate.cfg.xml文件中配置一个属性。该物业是

   <propertyname="hibernate.current_session_context_class">thread</property>

current_session_context_class的值将是, 线程(本地事务) 管理jta(全球交易)

  1. thread - 会话绑定到一个线程,如果你调用一个getCurrentSession(),它会返回一个相同的会话对象。

  2. 托管 - 这提供了来自某个外部实体的管理会话,如intercepter。在ThreadLocal中维护会话与&#34; thread&#34;相同类型,但有一个不同的方法,如bind(),unbind(),hasbind(),供外部实体用来在上下文中维护会话。

  3. jta - 会话将绑定到一个事务,因为我们说一个事务,然后我们需要应用服务器来使用这个上下文类。

     public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
        if ( currentSessionContext == null ) {
           throw new HibernateException( "No CurrentSessionContext configured!" );
        }
        return currentSessionContext.currentSession();  }
    
  4. 或试试这个

    Session session = sessionFactory.getCurrentSession();
    
    if (session.isOpen()) {
        session.close();
    }
    
    TransactionSynchronizationManager.unbindResource(sessionFactory);
    TransactionSynchronizationManager.clearSynchronization();