2009-07-30 17 views
1

在我學習冬眠的旅程中,我遇到了一篇關於hibernate site的文章。我也在學習春天,想通過讓你實現你自己的session來發現春天的靈活性。我不想使用hibernateTemplate(用於實驗)。而我現在有一個問題,甚至在測試class.I隨後在休眠網站尤其是部分 所以我們有通用的DAO接口的「用Hibernate實現」的文章:測試道與hibernate的春天genericdao模式.Headache

public interface GenericDAO<T, ID extends Serializable> { 

T findById(ID id, boolean lock); 

List<T> findAll(); 

List<T> findByExample(T exampleInstance); 

T makePersistent(T entity); 

void makeTransient(T entity); 

}

它在抽象類中的實現與網站上的實現相同。請參閱我提供的鏈接。我想保存該帖子爲時過長

現在來我的道的消息道接口

package com.project.core.dao; 

import com.project.core.model.MessageDetails; 
import java.util.List; 

public interface MessageDAO extends GenericDAO<MessageDetails, Long>{ 
//Message class is on of my pojo 
public List<Message> GetAllByStatus(String status); 


} 

其實現messagedaoimpl:

public class MessageDAOImpl extends GenericDAOImpl <Message, Long> implements MessageDAO { 

// mySContainer is an interface which my HibernateUtils implement 
    mySContainer sessionManager; 

/** 
* 
*/ 
public MessageDAOImpl(){} 

/** 
* 
* @param sessionManager 
*/ 
public MessageDAOImpl(HibernateUtils sessionManager){ 
this.sessionManager = sessionManager; 
} 
//........ plus other methods 
} 

這裏是我的HibernatUtils

public class HibernateUtils implements SessionContainer { 
private final SessionFactory sessionFactory; 
private Session session; 

public HibernateUtils() { 
    this.sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
} 

public HibernateUtils(SessionFactory sessionFactory) { 
    this.sessionFactory = sessionFactory; 
} 

/** 
* 
* this is the function that return a session.So i'm free to implements any type of session in here. 
*/ 
public Session requestSession() { 
//  if (session != null || session.isOpen()) { 
//   return session; 
//  } else { 
     session = sessionFactory.openSession(); 

//  } 
    return session; 
    } 
} 
在我的理解

所以在使用彈簧(將提供的conf),i'ld線SessionFactory來我HiberbernateUtils,然後將它的方法RequestSession連接到GenericDAOImpl的Session屬性(從提供的鏈接中獲得)。

這裏是我的Spring配置core.xml

<bean id="sessionManager" class="com.project.core.dao.hibernate.HibernateUtils"> 
    <constructor-arg ref="sessionFactory" /> 
</bean> 
<bean id="messageDao" class="com.project.core.dao.hibernate.MessageDAOImpl"> 
    <constructor-arg ref="sessionManager"/> 

    </bean> 
<bean id="genericDAOimpl" class="com.project.core.dao.GenericDAO"> 
    <property name="session" ref="mySession"/> 
    </bean> 
    <bean id="mySession" factory-bean="com.project.core.dao.SessionContainer" factory-method="requestSession"/> 

現在我的測試是這樣的

public class MessageDetailsDAOImplTest extends AbstractDependencyInjectionSpringContextTests{ 


HibernateUtils sessionManager = (HibernateUtils) applicationContext.getBean("sessionManager"); 
MessageDAO messagedao =(MessageDAO) applicationContext.getBean("messageDao"); 



static Message[] message = new Message[] 
{ 
    new Message("text",1,"test for dummies 1","1234567890","Pending",new Date()), 
    new Message("text",2,"test for dummies 2","334455669990","Delivered",new Date())   
}; 


public MessageDAOImplTest() { 
} 

@Override 
protected String[] getConfigLocations(){ 
    return new String[]{"file:src/main/resources/core.xml"}; 
} 

    @Test 
    public void testMakePersistent() { 
     System.out.println("MakePersistent"); 
    messagedao.makePersistent(message[0]); 
    Session session = sessionManager.RequestSession(); 
    session.beginTransaction(); 
    MessageDetails fromdb = (Message) session.load(Message.class, message[0].getMessageId()); 
    assertEquals(fromdb.getMessageId(), message[0].getMessageId()); 
    assertEquals(fromdb.getDateSent(),message.getDateSent()); 
    assertEquals(fromdb.getGlobalStatus(),message.getGlobalStatus()); 
    assertEquals(fromdb.getNumberOfPages(),message.getNumberOfPages()); 

    } 

我遇到這個錯誤

例外構造testMakePersistent( java.lang.NullPointerException在com.project.core.dao.hibernate.MessageDAOImplTest)

與此堆棧:在com.project.core.dao.hibernate.MessageDAOImplTest(MessageDAOImplTest.java:28) 在sun.reflect.NativeConstructorAccessorImpl.newInstance0(本機方法) 在sun.reflect.NativeConstructorAccessorImpl .newInstance(NativeConstructorAccessorImpl.java:39) 在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 在java.lang.reflect.Constructor.newInstance(Constructor.java:513) 在junit.framework.TestSuite .createTest(TestSuite.java:61) at junit.framework.TestSuite.addTestMethod(TestSuite.java:283) at junit.framework.Te stSuite。(TestSuite.java:146) at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:481) at org.apache.tools.ant.taskdefs.optional.junit .JUnitTestRunner.launch(JUnitTestRunner.java:1031) 在org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888) ))

如何真正使這一個工作。我知道這是很多東西,我感謝你閱讀它。請給我一個解決方案。你會怎麼做?感謝

回答

2

問候...我認爲你讓它變得比現在複雜。 :)

如果您使用Spring和Hibernate(您是),您並不需要創建自己的HibernateUtils來管理會話。如果你不使用Spring,HibernateUtils幾乎是必需的,否則它看起來多餘。這是乏味的,這是一個額外的代碼,你需要維護,你可能不會得到正確的。順便說一句,你的HibernateUtils似乎沒有正確實現。

這是我會怎麼做: -

  1. 您需要創建一個SessionFactory的bean: -

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="mappingResources"> 
        <list> 
         <value>// .. hbm files, omitted for brevity</value> 
        </list> 
    </property> 
    <property name="hibernateProperties"> 
        // .. dialect, etc... omitted for brevity 
    </property> 
    </bean> 
    
  2. 線該SessionFactory到你的DAO(和你需要一個二傳手你的DAO): -

    <bean id="messageDao" class="com.project.core.dao.hibernate.MessageDAOImpl"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 
    
  3. 要獲得你的dao中的連接,j執行sessionFactory.getCurrentSession()。而已。

通過將sessionFactory連接到您的測試用例中,您可以做同樣的事情。

下面是一些參考,如果你想知道如何春季與Hibernate集成: http://static.springsource.org/spring/docs/2.5.x/reference/orm.html

0

這似乎是無法調用MessageDAOImplTest構造,但因爲它是空的,我猜實際上,問題在於成員變量的初始化。哪一行是第28行?您可以嘗試將初始化邏輯移至構造函數主體,並使用調試器逐步完成,以查明問題。

順便說一句,你的方法有這樣的問題的DAO都是線程之間共享單身,但是Hibernate的會話不能在線程間共享,所以你需要將它們存儲爲ThreadLocal的。如果您使用Spring進行會話管理,則會自動發生。也許這對你並不重要,因爲這是一個「實驗」,但我想我會提出來的。

0

我可以看到的第一個問題是GenericDaoImpl類應該是抽象的(根據您提供的Hibernate鏈接),並且嘗試在Spring配置中實例化它(通過聲明bean'genericDAOImpl')。

您可以直接在'messageDao'bean上設置會話屬性(顯然是因爲MessageDAOImpl擴展了GenericDAOImpl)。所以我想你的Spring配置應該看起來更像是這樣的:

<bean id="sessionManager" class="com.project.core.dao.hibernate.HibernateUtils"> 
    <constructor-arg ref="sessionFactory" /> 
</bean> 
<bean id="messageDao" class="com.project.core.dao.hibernate.MessageDAOImpl"> 
    <constructor-arg ref="sessionManager"/> 
    <property name="session" ref="mySession"/> 
</bean> 
<bean id="mySession" factory-bean="com.project.core.dao.SessionContainer" factory-method="requestSession"/> 

我希望這有助於。這是我在SO上的第一個答案:-)。

+0

感謝活計,你讓我實現mistake.thanks我認爲現在是正常的 – 2009-08-11 15:53:37