如何正确测试Hibernate长度限制?

时间:2010-04-15 22:01:26

标签: java hibernate persistence

我有一个用Hibernate映射的POJO用于​​持久化。在我的映射中,我指定了以下内容:

<class name="ExpertiseArea">
    <id name="id" type="string">
        <generator class="assigned" />
    </id>
    <version name="version" column="VERSION" unsaved-value="null" />
    <property name="name" type="string" unique="true" not-null="true" length="100" />
    ...
</class>

我想测试一下,如果我设置的名称超过100个字符,则不会保留更改。我有一个DAO,我使用以下代码保存实体:

public T makePersistent(T entity){
    transaction = getSession().beginTransaction();
    transaction.begin();

    try{
        getSession().saveOrUpdate(entity);
        transaction.commit();
    }catch(HibernateException e){
        logger.debug(e.getMessage());
        transaction.rollback();
    }   
    return entity;
}

实际上上面的代码来自我所有DAO都继承自的GenericDAO。然后我创建了以下测试:

public void testNameLengthMustBe100orLess(){
    ExpertiseArea ea = new ExpertiseArea(
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890" +
        "1234567890");

    assertTrue("Name should be 100 characters long", ea.getName().length() == 100);

    ead.makePersistent(ea);
    List<ExpertiseArea> result = ead.findAll();
    assertEquals("Size must be 1", result.size(),1);

    ea.setName(ea.getName()+"1234567890");
    ead.makePersistent(ea);

    ExpertiseArea retrieved = ead.findById(ea.getId(), false);
    assertTrue("Both objects should be equal", retrieved.equals(ea));
    assertTrue("Name should be 100 characters long", (retrieved.getName().length() == 100));
}

该对象保持正常。然后我设置一个超过100个字符的名称并尝试保存更改,但失败了:

14:12:14,608  INFO StringType:162 - could not bind value '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' to parameter: 2; data exception: string data, right truncation
14:12:14,611  WARN JDBCExceptionReporter:100 - SQL Error: -3401, SQLState: 22001
14:12:14,611 ERROR JDBCExceptionReporter:101 - data exception: string data, right truncation
14:12:14,614 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.DataException: could not update: [com.exp.model.ExpertiseArea#33BA7E09-3A79-4C9D-888B-4263314076AF]

//Stack trace

14:12:14,615 DEBUG GenericDAO:87 - could not update: [com.exp.model.ExpertiseArea#33BA7E09-3A79-4C9D-888B-4263314076AF]
14:12:14,616 DEBUG JDBCTransaction:186 - rollback
14:12:14,616 DEBUG JDBCTransaction:197 - rolled back JDBC Connection

这是预期的行为。但是,当我检索持久化对象以检查其名称是否仍为100个字符时,测试失败。

我看到它的方式,检索到的对象应该有一个100个字符长的名称,因为尝试的更新失败了。最后一个断言失败,因为名称现在长度为110个字符,就像ea实例确实已更新一样。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

看来该对象首先存储在会话中(并缓存),并且在失败时它不会被驱逐。你必须session.evict(..)它。其他选项包括session.clear(..)session.refresh(..),以确保您使用的是数据库中的内容。

你拥有的是数据库限制,没有休眠。如果您根本不想访问数据库,可以使用Hibernate Validator@Length注释。 (Here是一篇新文章)