Garniture de chaîne de caractères en JPA
J'ai une db tableau avec les colonnes de type de données char(20). Je ne suis pas autorisé à le changer pour un varchar.
Je suis en train d'écrire une entité JPA mappés à cette table. J'aimerais que le champ de type chaîne de représentation de cette colonne dans ma classe entité contiennent toujours les garnis de valeur, et non pas la valeur de 20 caractères rembourré avec des espaces qui existe dans la base de données.
Je ne vois aucun moyen facile de le faire. (une annotation serait roche!). Pour le moment je suis juste de retour d'un garni de la valeur de mon getter(), mais cela se sent comme une bidouille.
Une recherche sur google offre pas d'aide sur ce. Des idées?
- Je me demandais ce qui allait se passer, si vous souhaitez utiliser
@ColumnDefinition
et de définir la colonne commeVARCHAR
même si c'est unCHAR
. Le plus probable serait le résultat soit le même ou d'une erreur. - L'annotation @ColumnDefinition n'est utile que lors de la production de la db schéma. Si vous n'avez pas l'esprit à l'aide de pure mise en veille prolongée et en s'écartant de la JPA standard, vous pouvez utiliser Hibernate @ColumnTransformer à condition que vous ayez une base de données pour faire le travail de Vous pouvez trouver comment le faire en Hibernation référence: docs.jboss.org/hibernate/core/3.6/reference/en-US/html/...
- Je ne vois pas quel est le problème avec votre solution originale. Votre apprpoach est la bonne. Comme vous pouvez le voir dans les réponses suggérées, il va pas faire plus simple que cela. La seule meilleure solution: modifier le champ de base de données VARCHAR, qui vous dit que vous ne pouvez pas.
- si nous parlons de l'un ou des deux propriétés, je suis d'accord. Si c'est un modèle qui apparaît tous sur une grande base de code, un auditeur est beaucoup plus fiable
- patrick floyd yep c'est comparants, tous sur une grande base de code.
- J'ai eu le même problème composées à la clé(les deux champs) valeur des espaces. Ne pouvait pas utiliser @test de charge de la fonction il a donné
Attempt to change a primary key field of an instance that already has a final object id. Only new, unflushed instances whose id you have not retrieved can have their primary keys changed.
. Je me suis installé sur l'utilisation dereturn id.trim()
dans une méthode de lecture.
Vous devez vous connecter pour publier un commentaire.
Ou vous pouvez utiliser du cycle de vie des annotations:
Si cela se produit sur plusieurs entités, vous pouvez créer une personnalisée d'annotation et d'écrire un dédié EntityListener.
Annotation
Auditeur
Maintenant annoter tous les champs de type Chaîne avec
@Trim
et enregistrer le port d'écoute par défaut de l'entité de l'écouteur dans votre persistence.xml:La accepté de répondre (en utilisant JPA entité auditeurs /@Garniture annotation) est dangereux. L'appel de la setter de l'extrait de l'entité apparaît de marque de l'entité en tant que sale. Quand j'ai essayé moi-même à une racine au niveau de l'entité (à l'aide de Spring3 /hibernate), il a déclenché des tonnes d'autres mises à jour liées à des entités qui n'étaient pas modifiés au cours de la transaction. C'était un vrai bordel dans la production et le suivi vers le bas pour ce qui est la cause a pris du temps.
À la fin, j'ai choisi d'aller avec l'approche plus directe de la coupe de chacun des champs manuellement à la demande (dans une entité personnalisée-à-domaine mappeur, ou dans l'entité de lecture) similaire à Edwin réponse.
@EntityListeners(YourListener.class)
sur mon Entité JPA avec@PostLoad
afin d'internaliser les Chaînes (c'est à diremyStringField.set(myEntity, ((String)myStringField.get(myEntity)).intern())
). Donc, mon approche est équivalente à Sean Patrick Floyd solution. Mais je n'ai jamais vu les "tonnes d'autres mises à jour" que vous mentionnez.@Trim
annotation, ce comportement a cessé.Ce fournisseur JPA utilisez-vous?
Si vous utilisez EclipseLink CHAR champs sont recouverts par défaut. Vous pouvez désactiver cette fonction par le biais de la session trimStrings propriété (assurez-vous que vous n'avez pas défini cette).
Je suis en utilisant cette méthode, ce qui rend la garniture transparente, sans avoir à utiliser des annotations dans chaque champ de type chaîne.
Dans le même package que vous avez votre session usine de classe (celle que vous utilisez pour obtenir des Séances, e.g
org.blablabla.yourpackage.etc.SessionGetter.getSession()
, vous devez créer un fichier nommépackage-info.java
et de mettre ce contenu à l'intérieur:Puis vous créez la classe
StringUserType
dans ce même package:Et c'est tout, pas besoin de créer des annotations dans vos haricots, il sera "comme par magie" couper les cordes à chaque fois que vous obtenir les objets de la base de données.
Accepté de répondre à des œuvres à l'exception de l'inscription de l'auditeur persistence.xml. Je l'ai fait avec orm.xml.
Mettre l'annotation sur la méthode de lecture, réglez le @Acesss à AccessType.De la propriété et de l'assiette au champ de l'aide de la Chaîne.trim() la méthode.
Ou tout simplement mettre la garniture dans la méthode de lecture et toujours l'accès au terrain à travers elle. Il ne va pas pour obtenir de plus simple.
Si vous n'avez pas l'esprit à l'aide de pure mise en veille prolongée et en s'écartant de la JPA standard, vous pouvez utiliser Hibernate @ColumnTransformer à condition que vous ayez une base de données pour faire le travail de
Vous pouvez trouver comment le faire en Hibernation référence:
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#mapping-column-read-and-write
J'espère que ça aide!
Tout ce que vous avez à faire est de le mettre sur votre contrôleur et il fonctionne comme prévu, vous n'avez pas besoin d'un écouteur ou quoi que ce soit de
Si votre domaine exigence états besoins garni d'informations, vous avez besoin de stocker les données dans garnis de valeur. Je ne vois rien de mal à cela.
Si vous explicitement d'appliquer la règle d'entreprise au niveau base de données, une option est que vous avez un choix de la rédaction d'un déclencheur, vous pouvez utiliser les haut-SQL méthode trim. Mais ce sera comme à l'aide d'une fusée à casser un œuf.