开发者

How to properly test Hibernate length restriction?

I have a POJO mapped with Hibernate for persistence. In my mapping I specify the following:

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

And I want to test that if I set a name longer than 100 characters, the change won't be persisted. I have a DAO where I save the entity with the following code:

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

Actually the code above is from a GenericDAO which all my DAOs inherit from. Then I created the following test:

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

The object is persisted ok. Then I set a name longer than 100 characters and try to save the changes, which fails:

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

That's expected behavior. However when I re开发者_StackOverflow社区trieve the persisted object to check if its name is still 100 characters long, the test fails.

The way I see it, the retrieved object should have a name that is 100 characters long, given that the attempted update failed. The last assertion fails because the name is 110 characters long now, as if the ea instance was indeed updated.

What am I doing wrong here?


It appears that the object is first stored in the session (and cached) and on failure it is not evicted. You you'd have to session.evict(..) it. Other options are session.clear(..) and session.refresh(..) to make sure you are working with what's in the database.

What you have is a database restriction, no hibernate. If you don't want to hit the database at all, you can use Hibernate Validator's @Length annotation. (Here is a fresh article)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜