2017-07-28 1 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; 
} 
} 

これが正しくフォーマットされている場合にも、私は謝罪。質問を投稿するのは初めてのことです。トランザクションの終了時に

ザスタックトレース

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

あなたが 'sessionFactory'がセッター注入で使用されているこの[example](https://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/)を参照しているとします。 –

+0

また、Daoクラスには '@ Repository'がありません。 [this](http://www.studytrails.com/frameworks/spring/spring-hibernate-session-factory-annotation/)も参照してください –

答えて

-1

セッションはgetCurrentSession()が最初に呼び出されるたびに開閉されます。既存のセッションが存在しない場合は新しいセッションが作成され、既存のセッションが存在する場合は既存のセッションが使用されます。オート・フラッシングとオート・クローズの両方の属性をtrueに設定すると、セッションは自動的にフラッシュされ閉じられます。

トランザクションが長時間実行されているときにgetCurrentSession()メソッドを使用できます。このメソッドを使用するには、hibernate.cfg.xmlファイルに1つのプロパティを設定する必要があります。シングルスレッドの実行のためのスレッドにバインドされたセッション、もし - プロパティはcurrent_session_context_classため

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

値は、 スレッド(ローカルトランザクション) 管理JTA(グローバルトランザクション)

  1. スレッドになりますですgetCurrentSession()を呼び出すと、同じセッションオブジェクトが返されます。

  2. managed - これは、いくつかの外部エンティティからのセッションを管理するために提供されたもので、インターセプタのようなものです。セッションをコンテキスト内で維持するために外部エンティティが使用するbind()、unbind()、hasbind()などの異なるメソッドを持つ、ThreadLocalのセッションを「スレッド」型と同じに保ちます。

  3. jta-sessionはトランザクションにバインドされますが、トランザクションとはこのコンテキストクラスを使用するためのアプリケーションサーバーが必要です。

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

それともSessionFactoryのフィールドがnullこの

Session session = sessionFactory.getCurrentSession(); 

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

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

Springを使用しているときは、 'hibernate.current_session_context_class'を使いこなしてはいけません。特にSpringと宣言的トランザクション管理との適切な統合を破るので、 'thread'に設定しないでください。 –

0

を試してみてください。

なぜ、私は推測することができます。 sessionFactoryフィールドを自動配線するだけでなく、applicationContext.xmlの設定を介してプロパティとして注入することもできます。両方を行うのではなく、どちらか一方を行い、何が起こるか見る。

関連する問題