我有一个用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
实例确实已更新一样。
我在这里做错了什么?
答案 0 :(得分:2)
看来该对象首先存储在会话中(并缓存),并且在失败时它不会被驱逐。你必须session.evict(..)
它。其他选项包括session.clear(..)
和session.refresh(..)
,以确保您使用的是数据库中的内容。
你拥有的是数据库限制,没有休眠。如果您根本不想访问数据库,可以使用Hibernate Validator的@Length
注释。 (Here是一篇新文章)