【问题标题】:Hibernate/Junit Testing : Data still remain in session even after closing and opening it or cleaning itHibernate/Junit 测试:即使在关闭和打开它或清理它之后,数据仍然保留在会话中
【发布时间】:2014-12-12 16:08:20
【问题描述】:

我在测试我的道时遇到了很多麻烦。 我会在最后展示代码。

问题是:

当我尝试在 dataDao 中测试不同的方法:addData 和 updateData 时,我想从一个干净的插槽重新开始。 如果我在添加后调用更新时不希望在 addData 的测试中添加数据。

我确实在 setUp 中打开一个会话并在 tearDown 中关闭它,分别用@Before 和@After 注释。 hibernate 配置是 create-drop,因此每次会话关闭和重新打开时表都是新的。

我对休眠有点陌生,但我做了研究,并在互联网上查找了相当长的时间/数周。

这是我正在测试的,两个类:DataDAO 和 MyDaoManager(他被使用是因为有不止一个表)

提前感谢您的帮助,

MyDaoManager.java

import java.util.List; 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public abstract class MyDaoManager<T> {

    private SessionFactory sessionFactory = null ;

    /**
     * <h2>Constructor which will get the sessionFactory from the class HibernateUtil</h2>
     */
    public MyDaoManager(){
        this.sessionFactory = HibernateUtil.getSessionFactory() ;
    }

    /**
     * <h2>Method which gets the SessionFactory.</h2>
     * @return A SessionFactory.
     */
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * <h2>Method which sets the SessionFactory at the moment of the construction.</h2>
     * @param sessionFactory The SessionFactory to set.
     */
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    /**
     * <h2>Method which adds a given object from the model in the database.</h2>
     * @param object Object to add.
     */
    public boolean add(T object){
        Session session = getSessionFactory().getCurrentSession();
        Transaction transaction = session.beginTransaction();

        try {
            session.save(object);
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }
        return true;
    }

    /**
     * <h2>Method which updates a given Object from the model in the database.</h2>
     * @param object Object to update.
     */
    public void update(T object){
        Session session = getSessionFactory().getCurrentSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.merge(object);
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }
    }

    /**
     * <h2>Method which saves or updates a given Object from the model in the database.</h2>
     * @param object Object to update.
     */
    public void saveOrUpdate(T object){
        Session session = getSessionFactory().getCurrentSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.saveOrUpdate(object);
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }
    }

    /**
     * <h2>Method which gets an object from the model thanks to its id in the database.</h2>
     * @param id The object's id to get.
     * @return An object.
     */
    public abstract T getOne(int id);

    /**
     * <h2>Method which gets all of an object from the model.</h2>
     * @return A list of the object.
     */
    public abstract List<T> getAll();

    /**
     * <h2>Method which deletes a given object thanks to its id.</h2>
     * @param id The object's id to delete.
     */
    public abstract void delete(int id);
}

这里是dataDao.java:

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class DataDao extends MyDaoManager<Data>{

    @Override
    public Data getOne(int id) {
        Session session = getSessionFactory().getCurrentSession();
        Transaction  transaction = session.beginTransaction();
        Data data = null;

        try {
            Query query = session.createQuery("from Data d where d.id= :id").setParameter("id", id);
            data = (Data)query.uniqueResult();
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }   
        return data;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Data> getAll() {
        Session session = getSessionFactory().getCurrentSession();
        Transaction  transaction = session.beginTransaction();
        List<Data> list = null;

        try {
            list = session.createQuery("from Data d").list();
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }   
        return list;
    }

    @Override
    public void delete(int id) {
        Session session = getSessionFactory().getCurrentSession();
        Data data = getOne(id);
        Transaction transaction = session.beginTransaction();
        try {
            session.delete(data);
            transaction.commit();
        }
        catch (RuntimeException e){
            transaction.rollback();
            throw e ;
        }
    }
}

这是我的测试,DataDaoTest.java:

import static org.junit.Assert.assertTrue;
import java.util.Date;
import java.util.List;    
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.hibernate.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class DataDaoTest{

    private Session session;
    private DataDao dataDao;

    @Before 
    public void setUp(){
        session = HibernateUtil.getSessionFactory().openSession();
        dataDao = new DataDao();
        dataDao.setSessionFactory(session.getSessionFactory());
    }

    @After
    public void tearDown(){
        session.close();
    }

    @Test
    public void addDataTestShouldWork(){
        Data dataTest = new Data();
        dataTest.setDate(new Date(System.currentTimeMillis()));
        dataTest.setSensor(new Sensor());
        dataTest.setValue("test");
        dataTest.setIsOnPhone(true);

        assertTrue("No add",dataDao.add(dataTest));

        List<Data> founded = dataDao.getAll();
        DataEqualsBuilder dataEqualsBuilder = new DataEqualsBuilder(dataTest);
        assertTrue("Not the same object added and founded", dataEqualsBuilder.equals(founded.get(0)));
    }

    @Test(expected=RuntimeException.class)
    public void addDataTestShouldNotWork(){
        dataDao.add(null);
    }

    @Test
    public void updateDataTestShouldWork(){
        Data dataTest = new Data();
        dataDao.add(dataTest);
        dataTest.setValue("test1");
        dataDao.update(dataTest);

        List<Data> founded = dataDao.getAll();
        DataEqualsBuilder dataEqualsBuilder = new DataEqualsBuilder(dataTest);

        assertTrue("Not the same object added and founded", dataEqualsBuilder.equals(founded.get(0)));
    }


    public class DataEqualsBuilder extends EqualsBuilder {

        private Data data;

        public DataEqualsBuilder( Data data){ this.data= data; }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) { return false; }
            if (obj == this) { return true; }
            if (obj.getClass() != data.getClass()) {
                return false;
            }
            Data rhs = (Data) obj;
            return (DataEqualsBuilder.reflectionEquals(data, rhs, "sensor"));
        }
    }
}

最后是我的休眠配置:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/APISensor</property>
        <!--  TODO create specific user -->
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>

        <property name="hbm2ddl.auto">create-drop</property>       

    </session-factory>
</hibernate-configuration>

【问题讨论】:

    标签: java hibernate junit dao


    【解决方案1】:

    尝试删除这个 Hibernate 属性:

    <property name="current_session_context_class">thread</property>
    

    并将您的设置/拆卸更改为:

    @Before 
    public void setUp(){        
        session = HibernateUtil.getSessionFactory().openSession();
        ThreadLocalSessionContext.bind(session);
        dataDao = new DataDao();
        dataDao.setSessionFactory(session.getSessionFactory());
    }
    
    @After
    public void tearDown(){
        session.close();
        ThreadLocalSessionContext.unbind(sessionFactory);
    }
    

    【讨论】:

    • 感谢您的帮助,不幸的是,我收到错误消息:错误测试:updateDataTestShouldWork(fr.sensor.api.dao.DataDaoTest):未配置 CurrentSessionContext! addDataTestShouldWork(fr.sensor.api.dao.DataDaoTest):未配置 CurrentSessionContext!此外,我确实更改了关于取消的行,因为没有变量 sessionFactory 所以改为: session.getSessionFactory()
    • 我回到你身边,因为我尝试了不同的解决方案,你的解决方案似乎更接近解决我的问题,谢谢你的帮助
    • 嗯,它已经接近了,但正如我告诉你的,我仍然有一个问题,我收到一个错误,没有配置当前会话上下文......
    猜你喜欢
    • 2015-01-03
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多