Est-il possible de définir une valeur par défaut pour les colonnes dans JPA, et si, comment cela se fait-il à l'aide d'annotations?
java
jpa
annotations
homaxto
la source
la source
Réponses:
En fait, c'est possible dans JPA, bien qu'un peu de piratage utilise la
columnDefinition
propriété de l'@Column
annotation, par exemple:la source
insertable=false
si la colonne est nullable (et pour éviter l'argument de colonne inutile).Vous pouvez effectuer les opérations suivantes:
Là! Vous venez d'utiliser zéro comme valeur par défaut.
Notez que cela vous servira si vous accédez uniquement à la base de données à partir de cette application. Si d'autres applications utilisent également la base de données, vous devez effectuer cette vérification à partir de la base de données à l'aide de l' attribut d' annotation columnDefinition de Cameron , ou d'une autre manière.
la source
Example
objet comme prototype pour la recherche. Après avoir défini une valeur par défaut, un exemple de requête Hibernate n'ignorera plus la colonne associée là où auparavant elle l'ignorerait car elle était nulle. Une meilleure approche consiste à définir toutes les valeurs par défaut juste avant d'appeler un Hibernatesave()
ouupdate()
. Cela imite mieux le comportement de la base de données qui définit les valeurs par défaut lors de l'enregistrement d'une ligne.null
par exemple). Utiliser@PrePersist
et@PreUpdate
est une meilleure option à mon humble avis.columnDefinition
La propriété n'est pas indépendante de la base de données et@PrePersist
remplace votre paramètre avant l'insertion, "valeur par défaut" est autre chose, la valeur par défaut est utilisée lorsque la valeur n'est pas définie explicitement.une autre approche utilise javax.persistence.PrePersist
la source
if (createdt != null) createdt = new Date();
quelque chose? À l'heure actuelle, cela remplacera une valeur explicitement spécifiée, ce qui semble ne pas être vraiment une valeur par défaut.if (createdt == null) createdt = new Date();
null
chèque.En 2017, JPA 2.1 n'a encore
@Column(columnDefinition='...')
de la définition littérale SQL de la colonne. Ce qui est assez peu flexible et vous oblige à déclarer également les autres aspects comme le type, court-circuitant le point de vue de l'implémentation JPA à ce sujet.Hibernate cependant, a ceci:
Deux notes à cela:
1) N'ayez pas peur de devenir non standard. En tant que développeur JBoss, j'ai vu pas mal de processus de spécification. La spécification est fondamentalement la référence que les grands acteurs dans un domaine donné sont prêts à s'engager à soutenir pour la prochaine décennie. C'est vrai pour la sécurité, pour la messagerie, ORM ne fait aucune différence (bien que JPA couvre beaucoup). Mon expérience en tant que développeur est que dans une application complexe, vous aurez besoin de toute façon tôt ou tard d'une API non standard. Et
@ColumnDefault
est un exemple lorsqu'il dépasse les inconvénients de l'utilisation d'une solution non standard.2) C'est agréable de voir comment tout le monde agite l'initialisation de @PrePersist ou du membre constructeur. Mais ce n'est pas pareil. Qu'en est-il des mises à jour SQL groupées? Que diriez-vous des déclarations qui ne définissent pas la colonne?
DEFAULT
a son rôle et ce n'est pas substituable en initialisant un membre de classe Java.la source
JPA ne supporte pas cela et ce serait utile si c'était le cas. L'utilisation de columnDefinition est spécifique à la base de données et n'est pas acceptable dans de nombreux cas. la définition d'une valeur par défaut dans la classe n'est pas suffisante lorsque vous récupérez un enregistrement ayant des valeurs nulles (ce qui se produit généralement lorsque vous réexécutez d'anciens tests DBUnit). Ce que je fais c'est ceci:
La boxe automatique Java y contribue beaucoup.
la source
Voyant que je suis tombé sur Google en essayant de résoudre le même problème, je vais juste jeter la solution que j'ai préparée au cas où quelqu'un la trouverait utile.
De mon point de vue, il n'y a vraiment qu'une seule solution à ce problème - @PrePersist. Si vous le faites dans @PrePersist, vous devez vérifier si la valeur a déjà été définie.
la source
@PrePersist
J'opterais certainement pour le cas d'utilisation d'OP.@Column(columnDefinition=...)
ne semble pas très élégant.Je viens de tester le problème. Cela fonctionne très bien. Merci pour l'astuce.
À propos des commentaires:
Celui-ci ne définit pas la valeur de colonne par défaut dans la base de données (bien sûr).
la source
vous pouvez utiliser l'api java reflect:
Ceci est courant:
la source
Field[] fields = object.getClass().getDeclaredFields();
dansfor()
pourrait également être correct. Et ajoutez égalementfinal
à vos exceptions de paramètre / prises car vous ne voulez pasobject
être modifié par accident. Ajoutez également un contrôle surnull
:if (null == object) { throw new NullPointerException("Parameter 'object' is null"); }
. Cela garantit que c'estobject.getClass()
sûr à invoquer et ne déclenche pas unNPE
. La raison est d'éviter les erreurs des programmeurs paresseux. ;-)J'utilise
columnDefinition
et ça marche très bienla source
Vous ne pouvez pas faire cela avec l'annotation de colonne. Je pense que la seule façon est de définir la valeur par défaut lors de la création d'un objet. Peut-être que le constructeur par défaut serait le bon endroit pour le faire.
la source
@Column
around. Et je manque également de définir des commentaires (tirés de Java doctag).Dans mon cas, j'ai modifié le code source hibernate-core, enfin, pour introduire une nouvelle annotation
@DefaultValue
:Eh bien, c'est une solution d'hibernation uniquement.
la source
@Column(columnDefinition='...')
ne fonctionne pas lorsque vous définissez la contrainte par défaut dans la base de données lors de l'insertion des données.insertable = false
et supprimercolumnDefinition='...'
de l'annotation, puis la base de données insérera automatiquement la valeur par défaut de la base de données.insertable = false
Hibernate / JPA, cela fonctionnera.la source
Dans mon cas, en raison du champ LocalDateTime que j'ai utilisé, il est recommandé en raison de l'indépendance du fournisseur
la source
Ni les annotations JPA ni Hibernate ne prennent en charge la notion de valeur de colonne par défaut. Pour contourner cette limitation, définissez toutes les valeurs par défaut juste avant d'appeler une mise en veille prolongée
save()
ouupdate()
sur la session. Cela aussi étroitement que possible (à moins qu'Hibernate ne définisse les valeurs par défaut) imite le comportement de la base de données qui définit les valeurs par défaut lorsqu'elle enregistre une ligne dans une table.Contrairement à la définition des valeurs par défaut dans la classe de modèle comme le suggère cette réponse alternative , cette approche garantit également que les requêtes de critères qui utilisent un
Example
objet comme prototype pour la recherche continueront de fonctionner comme auparavant. Lorsque vous définissez la valeur par défaut d'un attribut nullable (celui qui a un type non primitif) dans une classe de modèle, une requête Hibernate par exemple n'ignorera plus la colonne associée là où auparavant elle l'ignorerait car elle était nulle.la source
Ce n'est pas possible dans JPA.
Voici ce que vous pouvez faire avec l'annotation de colonne: http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html
la source
Si vous utilisez un double, vous pouvez utiliser ce qui suit:
Oui, c'est spécifique à la base de données.
la source
Vous pouvez définir la valeur par défaut dans le concepteur de base de données ou lorsque vous créez la table. Par exemple, dans SQL Server, vous pouvez définir le coffre-fort par défaut d'un champ Date sur (
getDate()
). Utilisezinsertable=false
comme indiqué dans la définition de votre colonne. JPA ne spécifiera pas cette colonne dans les insertions et la base de données générera la valeur pour vous.la source
Tu dois
insertable=false
dans votre@Column
annotation. JPA ignorera alors cette colonne lors de l'insertion dans la base de données et la valeur par défaut sera utilisée.Voir ce lien: http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html
la source
nullable=false
échouera avecSqlException
:Caused by: java.sql.SQLException: Column 'opening_times_created' cannot be null
. Ici, j'ai oublié de définir l'horodatage "créé" avecopeningTime.setOpeningCreated(new Date())
. C'est une bonne façon d'avoir de la cohérence, mais c'est ce que l'interrogateur ne demandait pas.