一个简单的Dao集成测试不起作用

时间:2011-12-10 14:04:52

标签: java hibernate spring tdd hibernate-generic-dao

这是一个非常简单的测试,用于在数据库中持久保存一个临时Person对象,然后验证该对象是否保存在 数据库与瞬态Person对象相同。 这是测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/daoIntegration-test.xml")
@Transactional
public class HibernatePersonDaoIntegrationTest {
    @Autowired
    private PersonDao PersonDao;
    @Autowired
    private SessionFactory sessionFactory;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void shouldSavePerson() {
        //Given
        Person person = new Person();

        //When
        PersonDao.savePerson(person);

        //Then ----THIS ASSERTION PASSES!!!
        assertThat(person.getId(), notNullValue());
        //And ----THIS ONE FAILS!!!
        Person persistedPerson = jdbcTemplate.queryForObject("select * from table_Person", Person.class);
        assertThat(persistedPerson, is(person));
    }

我的daoIntegration-test.xml

<jdbc:embedded-database id="dataSource" type="HSQL"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="packagesToScan" value="com.domain"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean> 
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

域类是:

@Entity
@Table(name="table_Person")
public class Person {

    @Id
    @TableGenerator(name = "seq_table", table = "GENERATOR_TABLE")
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_table")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private Long id;
    private String personFirstName;
...

第一个断言通过,但第二个断言失败了,我在某个地方犯了一个愚蠢的错误,但不知道在哪里!!!

2 个答案:

答案 0 :(得分:4)

第一个可能的问题

第二个断言失败只是因为它返回了Person个对象的不同实例。由于您没有(?)定义equals() / hashCode(),因此is()匹配器失败。

实现它们(这通常是Hibernate的一个好主意)。

第二个可能的问题

第一个断言通过,因为Hibernate从seq_table获取了id但尚未刷新实体本身。这意味着该实体位于第一级缓存中,但尚未存在于数据库中。因此,当您使用JDBC直接查询数据库时:

jdbcTemplate.queryForObject("select * from table_Person", Person.class);

找不到记录。保存实体或使用JPA查询对象后调用flush()。 Hibernate非常聪明,可以在flush()之前查询。

答案 1 :(得分:1)

您正在执行SELECT *查询,只有在数据库中有一行时才会返回一个对象。

如果查询没有返回一行,或者没有返回一个对象,则抛出IncorrectResultSizeDataAccessException

您确定不会抛出异常吗?

您的Person类是否实现了equals和hashCode correctly?如果is()方法取决于这些,则它不能比你的实现允许的更好。