2017-07-28 194 views
1

UsersDAOImpl类应该在我将该文件作为JUnit测试运行时添加新用户,但是当我调用sessionFactory.getCurrentSession()时我不断收到NullPointerException,而我不知道为什么。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 protected]", "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; 
} 
} 

另外,我很抱歉,如果这是正确格式化。这是我第一次发布一个问题。每当的getCurrentSession()被调用首次

堆栈跟踪

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) 

+0

假设您共享异常的完整堆栈跟踪。这可能会有所帮助。 –

+0

假设你引用这个[示例](https://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/),其中'sessionFactory'与setter注入一起使用。 –

+0

另外我没有在你的Dao类中看到'@ Repository'。请参阅[this](http://www.studytrails.com/frameworks/spring/spring-hibernate-session-factory-annotation/) –

回答

-1

会话被打开和关闭时在事务结束。这会创建一个全新的会话(如果不存在的话)或使用现有的会话(如果已经存在的话)。它会自动配置自动刷新和自动关闭属性为true,这意味着会话将自动刷新并关闭。

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

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

值的current_session_context_class会, 线程(本地事务) 管理的JTA(全局事务)

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

  2. 托管 - 这是为了管理来自某个外部实体的会话而设置的,例如intercepter。在ThreadLocal中维护会话的方式与“线程”类型相同,但具有不同的方法,如外部实体使用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(); } 
    

或者试试这个

Session session = sessionFactory.getCurrentSession(); 

if (session.isOpen()) { 
    session.close(); 
} 

TransactionSynchronizationManager.unbindResource(sessionFactory); 
TransactionSynchronizationManager.clearSynchronization(); 
+0

使用Spring时,不要乱用'hibernate.current_session_context_class'。特别是不要将它设置为'thread',因为这将破坏与Spring的正确集成以及声明式事务管理。 –

0

SessionFactory的字段为空。

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

相关问题