javahibernatespringtddhibernate-generic-dao

A simple Dao integration test not working


This is a very simple test about persisting a transient Person Object in the database and then verifying that the object saved in the database is the same as the transient Person object. Here goes the test

@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));
    }

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

Domain class is:

@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;
...

The first assertion passes, but the second one fails, I'm making a silly mistake somewhere but don't know where!!!


Solution

  • First possible problem

    The second assertions fails simply because it returns a different instance of Person object. Since you are not (?) defining equals()/hashCode(), the is() matcher fails.

    Implement them (this is generally a good idea with Hibernate).

    Second possible problem

    The first assertion passes because Hibernate fetched id from seq_table but haven't yet flushed the entity itself. This means the entity is in first level cache, but not yet in the database. Thus when you are querying the database directly using JDBC:

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

    The record is not found. Call flush() after saving an entity or query the object using JPA. Hibernate is clever enough to flush() prior querying.