2010-04-15 2 views
1

J'ai un POJO mappé avec Hibernate pour la persistance. Dans mon application, je précise ce qui suit:Comment tester correctement la restriction de longueur d'Hibernate?

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

Et je veux tester que si je mets un nom plus de 100 caractères, le changement ne sera pas persisté. J'ai un OAC où je sauverai l'entité avec le code suivant:

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

En fait, le code ci-dessus est d'un GenericDAO qui tous mes OTI héritent. Ensuite, j'ai créé le test suivant:

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

L'objet est conservé ok. Ensuite, je mets un nom plus de 100 caractères et essayez d'enregistrer les modifications, qui échoue:

14:12:14,608 INFO StringType:162 - could not bind value '123456789' 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 

C'est le comportement attendu. Cependant lorsque je récupère l'objet persistant pour vérifier si son nom est toujours de 100 caractères, le test échoue. Comme je le vois, l'objet récupéré devrait avoir un nom de 100 caractères, étant donné que la tentative de mise à jour a échoué. La dernière assertion échoue car le nom a maintenant 110 caractères, comme si l'instance ea était bien mise à jour.

Qu'est-ce que je fais mal ici?

+3

Essayez d'effacer la session, cela peut être un problème de mise en cache. – lexicore

+0

Je voudrais vraiment que votre commentaire soit une réponse à la place, parce que c'était exactement le problème. Merci lexicore! – Cesar

Répondre

2

Il semble que l'objet est d'abord stocké dans la session (et mis en cache) et en cas d'échec, il n'est pas expulsé. Vous vous devez session.evict(..). Les autres options sont session.clear(..) et session.refresh(..) pour vous assurer que vous travaillez avec ce qui est dans la base de données.

Ce que vous avez est une restriction de base de données, pas d'hibernation. Si vous ne voulez pas toucher la base de données, vous pouvez utiliser l'annotation @Length de Hibernate Validator. (Here est un nouvel article)

+0

Merci pour l'explication et la suggestion sur l'utilisation des validateurs Hibernate. J'accepte cette réponse comme acceptée. – Cesar

Questions connexes