0

这是一个非常简单的测试,关于在数据库中持久化一个瞬态 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;
...

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

4

2 回答 2

4

第一个可能的问题

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

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

第二个可能的问题

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

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

找不到记录。flush()保存实体后调用或使用 JPA 查询对象。Hibernate 足够聪明,可以flush()预先查询。

于 2011-12-10T14:14:08.277 回答
1

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

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

你确定没有抛出异常吗?

您的 Person 类是否正确实现了 equals 和 hashCode ?如果 is() 方法依赖于这些,那么它不会比您的实现允许的更好。

于 2011-12-10T14:13:31.340 回答