java - hibernate/Junit 测试 : Data still remain in session even after closing and opening it or cleaning it

标签 java hibernate junit dao

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

问题是:

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

我确实在setUp中打开一个 session ,并在tearDown中关闭它,并分别用@Before和@After进行注释。 hibernate 配置是创建-删除的,因此每次 session 关闭和重新打开时表都是新的。

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

这是我正在测试的,两个类: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"));
        }
    }
}

最后是我的 hibernate 配置:

<?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>

最佳答案

尝试删除此 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);
}

关于java - hibernate/Junit 测试 : Data still remain in session even after closing and opening it or cleaning it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27447557/

相关文章:

java - 有没有更好的方法 - Java 条件语句

java - java sound 流音频的奇怪问题

hibernate - 查询关联所在的Grails

java - ExpectedSystemExit 导致错误

java - JCommander 是否支持没有前缀的动态参数?

java - Hibernate 对自定义集合的查询

java - 在 Spring Data JPA 中连接两个表并从存储库查询两个表数据

java - 在调用验证方法后更改值属性时,ArgumentCaptor.getValue() 上的 assertThat 误报

eclipse - JUnit Eclipse插件源代码?

java - 如何检查查询最终传递的参数是什么?