代码之家  ›  专栏  ›  技术社区  ›  Cesar

如何正确测试休眠长度限制?

  •  1
  • Cesar  · 技术社区  · 16 年前

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

    实际上,上面的代码来自一个GenericDAO,我的所有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个字符长时,测试失败。

    ea

    我做错什么了?

    1 回复  |  直到 16 年前
        1
  •  2
  •   Bozho    16 年前

    似乎该对象首先存储在会话中(并被缓存),一旦失败,它不会被逐出。你必须这样做 session.evict(..) 是的。其他选择包括 session.clear(..) session.refresh(..)

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