2013-06-27 2 views
3

J'ai un fichier de mappage qui spécifie une colonne donnée comme not-null="true". Ceci est une erreur car la colonne de la table est définie sur NULL dans la base de données Oracle. Mais nous n'avons pas remarqué cela jusqu'à maintenant, plus d'un an après la création du fichier de mapping, parce que Hibernate a "ignoré" cela. Est-ce possible?saveOrUpdate de Hibernate ignore la propriété de la colonne not-null

Pour le rendre plus clair. Sur la base de données:

CREATE TABLE db.my_table
(...)
my_column NUMBER(10,0) NULL, (...)

sur le fichier de mapping:

<column name="MY_COLUMN" precision="10" scale="0" not-null="true">

Ensuite, le code Java:

getHibernateTemplate().saveOrUpdate(myEntity);

getHibernateTemplate().flush();

Ce code fonctionne sur notre environnement. A toujours été. Mais certains clients ont eu des problèmes de ot-null property references a null or transient value et quand j'ai débogué le code cela n'avait aucun sens. Ce code ne devrait jamais pouvoir fonctionner, autant que je sache.

Bien sûr, il est simple de résoudre les problèmes des clients, je dois juste corriger le fichier de mappage afin qu'il représente correctement mon entité. Mais le vrai problème ici est pourquoi Hibernate ne s'en est-il pas plaint?

J'ai demandé à d'autres ingénieurs ici avec plus d'expérience sur Hibernate mais aucun d'eux n'a jamais vu ça.

Alors, quelqu'un peut-il donner un indice?

EDIT: Je veux juste souligner que la fois notre environnement de test et sont en cours d'exécution exactement le même code de mon client, et dans les deux cas, l'objet myEntity a l'ensemble de la propriété myColumn-NULL. Donc, ce qui me laisse perplexe, c'est pourquoi il n'y a aucune exception ici sur notre environnement.

+0

C'est un bug. Je suppose que chaque morceau de logiciel en a un. –

+0

Ça sent sûrement comme un bug. Mais je me demande pourquoi cela n'arrive pas sur notre environnement, mais seulement sur nos clients. –

Répondre

3

Le comportement est absolument correct.

L'not-null attribut a deux significations:

  • schéma support des outils d'exportation
  • vérifier l'entité d'exécution (ie ne paramètre colonne de base de données vérifie pas)

Voir: 5.1. Mapping declaration, extrait:

Le document de cartographie contient également un peu plus attributs facultatifs et éléments qui affectent les schémas de base de données exportés par l'outil d'exportation de schéma (par exemple, l'attribut non nul).

Et 5.1.11. Property, extrait:

not-null (facultatif): permet la génération de DDL d'une contrainte nullabilité pour les colonnes.

Donc, si vos clients exécutent un code qui tente:

getHibernateTemplate().saveOrUpdate(myEntity); 

alors que le myEntity manque une propriété définie comme not-null="true" il est correct à jeter une exception d'exécution. Alors que dans votre environnement de test, vous définissez toujours la propriété sur , la valeur n'est pas nulle.

Et il y a même un avantage. La base de données et l'application sont faiblement couplés. Donc, en cas de besoin, vous pouvez faire plus de contraintes sur le côté App, tout en ne touchant pas le DB (par exemple, vous n'êtes pas autorisé)

+0

Qu'il a une influence sur le DDL est logique, mais, l'autre partie, je suis confus: un appel à 'getHibernateTemplate(). SaveOrUpdate (myEntity);' où 'myEntity' a la propriété mappée à' MY_COLUMN' avec ' null' donnera une erreur d'exécution ou non? – acdcjunior

+0

S'il y a un mapping: 'not-null = true', et que l'entité a la valeur NULL au lieu de la valeur ... elle finira par une erreur d'exécution. En fait, en exception: * la propriété not-null référence une valeur nulle ou transitoire * –

+1

Ok, compris! Peut-être que vous devriez envisager de changer cela * "Donc, si vos clients exécutent du code, qui essaie:' getHibernateTemplate().saveOrUpdate (myEntity); ' alors que le' myEntity' manque une propriété définie comme 'not-null =" true "' ** c'est correct **. "* * Cette dernière partie (en gras) est ce qui m'a dérouté Je m'attendrais à quelque chose comme "il est correct de lancer une exception d'exécution." Ou toute autre chose ... Bonne réponse! +1! – acdcjunior

1

J'ai eu exactement le même problème:

Dans mon fichier de mappage de mise en veille prolongée, je l'avais mis not-null="true" pour une colonne spéciale.

Sur ma machine de développement je pourrais persister les valeurs nulles sans aucune exception. Sur la machine des clients nous toujours reçu un PropertyValueException/DataIntegrityViolationException.

Ce comportement était dangereux. Les tests manuels et automatiques n'échoueraient pas.

Solution:

Sur mon chapeau machine de développement I pour définir la propriété hibernate.check_nullability à true. Seulement alors j'ai aussi obtenu les exceptions sur mon système de développement.

Conclusion

Ce comportement étrange pourrait venir d'ajouter l'hibernate validator au classpath. Cela devient check_nullability à false. Voir cette question connexe: How to Enable Spring Validation

D'une certaine manière cela ne s'applique que sur mon système de développement et non en production. Cela peut provenir d'une charge de dépendance différente au sein de différents serveurs d'applications.

Questions connexes