тестирование дао с гибернацией шаблонов genericdao с пружиной. Головная боль - PullRequest
1 голос
/ 30 июля 2009

В моем пути изучения гибернации я наткнулся на статью на сайте гибернации . Я тоже изучаю Spring и хотел сделать определенные вещи, чтобы раскрыть гибкость Spring, позволяя вам реализовать свой собственный сеанс. Да, я не хочу использовать hibernateTemplate (для эксперимента). и теперь у меня есть проблема и даже тестовый класс. Я следил за статьей на сайте hibernate, особенно за разделом "реализация с hibernate" Итак, у нас есть универсальный дао-интерфейс:

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);


}

его реализация представлена ​​в сообщении:

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;
  }
}

Таким образом, в моем понимании при использовании spring (предоставит conf) я подключу sessionFactory к моему HiberbernateUtils, а затем подключу его метод RequestSession к свойству Session свойства GenericDAOImpl (тот, который предоставлен по указанной ссылке).

вот мой весенний конфиг 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) at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (собственный метод) в sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) в java.lang.reflect.Constructor.newInstance (Constructor.java:513) в junit.framework.TestSuite.createTest (TestSuite.java:61) в junit.framework.TestSuite.addTestMethod (TestSuite.java:283) на junit.framework.TestSuite. (TestSuite.java:146) в org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run (JUnitTestRunner.java:481) в org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch (JUnitTestRunner.java:1031) в org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main (JUnitTestRunner.java:888) ))

Как на самом деле заставить это работать. Я знаю, что это очень много для вещей, и я благодарю вас за чтение. Пожалуйста, дайте мне решение. Как бы вы это сделали? спасибо

Ответы [ 3 ]

2 голосов
/ 15 мая 2010

Привет ... Я думаю, вы делаете это более сложным, чем оно есть. :)

Если вы используете Spring и Hibernate (которым вы являетесь), вам не нужно создавать собственные HibernateUtils для управления сеансом. HibernateUtils почти необходим, если вы не используете Spring, или он кажется избыточным. Это утомительно, это один дополнительный код, который вам нужно поддерживать, и вы, вероятно, не поймете его правильно. Кстати, ваш HibernateUtils, похоже, не реализован правильно.

Вот как бы я это сделал: -

  1. Вам необходимо создать bean-компонент sessionFactory: -

    <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. Подключите эту сессионную фабрику к вашему DAO (и вам также нужен установщик в вашем DAO): -

    <bean id="messageDao" class="com.project.core.dao.hibernate.MessageDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
  3. Чтобы получить соединение в вашем дао, просто выполните sessionFactory.getCurrentSession (). Вот и все.

Вы делаете то же самое, подключая sessionFactory к своему тестовому сценарию.

Вот некоторая справка, если вы хотите знать, как интегрировать Spring с Hibernate: http://static.springsource.org/spring/docs/2.5.x/reference/orm.html

0 голосов
/ 10 августа 2009

Первая проблема, которую я вижу, состоит в том, что класс GenericDaoImpl должен быть абстрактным (в соответствии с предоставленной вами ссылкой на спящий режим), и вы пытаетесь создать его экземпляр в своей конфигурации Spring (объявив компонент 'genericDAOImpl').

Вы можете установить свойство сеанса непосредственно в бине 'messageDao' (очевидно, потому что MessageDAOImpl расширяет GenericDAOImpl). Поэтому я думаю, что ваш весенний конфиг должен выглядеть примерно так:

<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 голосов
/ 01 августа 2009

Кажется, что не удается вызвать конструктор MessageDAOImplTest , но, поскольку он пуст, я предполагаю, что проблема на самом деле заключается в инициализации переменных-членов.Какая строка является строкой 28?Вы можете попытаться переместить логику инициализации в тело конструктора и пройтись по ней с помощью отладчика, чтобы точно определить проблему.

Кстати, у вашего подхода есть проблема в том, что DAO являются одиночными, общими для всех потоков, ноСеансы гибернации не должны быть общими для всех потоков, поэтому их нужно хранить как ThreadLocal .Если вы используете Spring для управления сессиями, это происходит автоматически.Может быть, это не важно для вас, потому что это «эксперимент», но я подумал, что я это подниму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...