Spring + Hibernate:使用JUnit初始化数据库不起作用

时间:2011-12-28 17:21:03

标签: java hibernate spring transactions junit

我有一个带有一个Vehicle表的简单数据库(使用MySQL):

create table vehicle (
    vehicle_no varchar(10) not null,
    color varchar(10),
    wheel int,
    seat int,
    primary key (vehicle_no)
) engine = InnoDB;

在Java中,我有DAO对象应该查询所有车辆(DAO的其他方法是ommited)。此DAO应加入现有事务或根据需要创建新事务:

@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public class HibernateVehicleDao implements VehicleDao {

    private SessionFactory sessionFactory;
    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public List<Vehicle> findAll() {
        return currentSession().createQuery("from Vehicle").list();
    }
}

现在,我已经为DAO编写了JUnit测试(JUnit4)。在运行测试方法之前,应该将10辆车插入数据库,运行后应删除所有车辆。我使用Spring的JDBC 单独测试这种行为,一切正常,所以应该没有问题。

@ContextConfiguration(locations = "/sk/xorty/dataaccess/dataaccess-beans.xml")
public class HibernateVehicleDaoTest extends AbstractTransactionalJUnit4SpringContextTests {

    private static final int COUNT = 10;

    @Autowired
    @Qualifier("hibernateVehicleDao")
    private VehicleDao dao;

    @Before
    public void setUp() {
        String insert = 
                "INSERT INTO VEHICLE (VEHICLE_NO, COLOR, WHEEL, SEAT) VALUES (?, ?, ?, ?)";
        List<Object[]> argsList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            argsList.add(VehicleUtil.nextVehicleArgs());
        }
        simpleJdbcTemplate.batchUpdate(insert, argsList);
    }

    @After
    public void tearDown() {
        simpleJdbcTemplate.update("DELETE FROM VEHICLE", (Object[]) null);
    }

    @Test
    public void testFindAll() {
        assertEquals (COUNT, dao.findAll().size());
    }
}

所有内容都会加载,所以我怀疑配置是否正确,并且正确地注入了依赖项。

问题,该测试失败,因为数据库为空(没有车辆)。当我手动插入它们时,它们永远不会被删除。

请尝试注意使用交易注释,我对此相当陌生,我认为我可能在某处犯了错误。

这是我的bean配置文件,如果可能有任何帮助:

<?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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <context:annotation-config />
    <tx:annotation-driven />

    <!-- shared data source -->
    <bean id="dataSource" 
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" 
            value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
        <property name="url" value="jdbc:mysql://localhost/vehicles" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <!-- JDBC transaction manager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses" >
            <list>
                <value>sk.xorty.dataaccess.Vehicle</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property> 
    </bean>

    <bean id="hibernateVehicleDao" class="sk.xorty.dataaccess.HibernateVehicleDao" />

</beans>

编辑:请求的车辆实体代码:

@Entity
@Table(name="vehicle")
public class Vehicle implements Serializable {

    @Id
    @Column(name="VEHICLE_NO", nullable=false, length=10)
    private String vehicleNo;
    private String color;
    private int wheel;
    private int seat;

    public Vehicle() {}

    public Vehicle(String vehicleNo, String color, int wheel, int seat) {
        this.vehicleNo = vehicleNo;
        this.color = color;
        this.wheel = wheel;
        this.seat = seat;
    }

    public String getVehicleNo() {
        return vehicleNo;
    }

    public void setVehicleNo(String vehicleNo) {
        this.vehicleNo = vehicleNo;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getWheel() {
        return wheel;
    }

    public void setWheel(int wheel) {
        this.wheel = wheel;
    }

    public int getSeat() {
        return seat;
    }

    public void setSeat(int seat) {
        this.seat = seat;
    }

    @Override
    public String toString() {
        return "Vehicle [vehicleNo=" + vehicleNo + ", color=" + color
                + ", wheel=" + wheel + ", seat=" + seat + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((color == null) ? 0 : color.hashCode());
        result = prime * result + seat;
        result = prime * result
                + ((vehicleNo == null) ? 0 : vehicleNo.hashCode());
        result = prime * result + wheel;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Vehicle other = (Vehicle) obj;
        if (color == null) {
            if (other.color != null)
                return false;
        } else if (!color.equals(other.color))
            return false;
        if (seat != other.seat)
            return false;
        if (vehicleNo == null) {
            if (other.vehicleNo != null)
                return false;
        } else if (!vehicleNo.equals(other.vehicleNo))
            return false;
        if (wheel != other.wheel)
            return false;
        return true;
    }

}

1 个答案:

答案 0 :(得分:-2)

我不确定这是否重要,但以下方法中的外壳不正确:

@Override
public List<Vehicle> findAll() {
    return currentSession().createQuery("from Vehicle").list();
}

表名以“vehicle”中的小写v开头,而此方法使用大写“V”。

我从文档中读到的另一个有趣的事情是:

  

simpleJdbcTemplate:用于查询以确认状态。例如,   您可以在测试创建的应用程序代码之前和之后查询   一个对象并使用ORM工具将其持久化,以验证数据   出现在数据库中。 (Spring将确保查询运行   同一交易的范围。)您需要告诉您的ORM   例如,用于“刷新”其更改以使其正常工作的工具   在Hibernate的Session接口上使用flush()方法。

在执行查询之前尝试刷新会话。