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

最初のアサーションは成功しますが、2 番目のアサーションは失敗します。

4

2 に答える 2

4

最初に考えられる問題

2 番目のアサーションは、オブジェクトの別のインスタンスを返すという理由だけで失敗しPersonます。equals()/を定義 (?) していないためhashCode()is()マッチャーは失敗します。

それらを実装します (これは通常、Hibernate では良い考えです)。

考えられる 2 番目の問題

最初のアサーションは、Hibernate が id を取得しseq_tableたがエンティティ自体をまだフラッシュしていないため、パスします。これは、エンティティが第 1 レベルのキャッシュにあるが、データベースにはまだないことを意味します。したがって、JDBC を使用してデータベースに直接クエリを実行する場合:

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

レコードが見つかりません。flush()エンティティを保存した後に呼び出すか、JPA を使用してオブジェクトをクエリします。flush()Hibernate は、事前にクエリを実行するのに十分賢いです。

于 2011-12-10T14:14:08.277 に答える
1

SELECT *データベースに 1 つの行がある場合にのみ 1 つのオブジェクトを返すクエリを実行しています。

クエリが正確に 1 つの行を返さない場合、または正確に 1 つのオブジェクトを返さない場合、 aIncorrectResultSizeDataAccessExceptionがスローされます。

例外がスローされていないことは確かですか?

あなたの Person クラスは equals と hashCodeを正しく実装していますか? is() メソッドがこれらに依存している場合、実装が許容する以上のものはありません。

于 2011-12-10T14:13:31.340 に答える