Réponses:
@Transient répond à vos besoins.
Pour ignorer un champ, annotez-le avec @Transientafin qu'il ne soit pas mappé en hibernation.
mais jackson ne sérialisera pas le champ lors de la conversion en JSON.
Si vous avez besoin de mélanger JPA avec JSON (omis par JPA mais toujours inclus dans Jackson), utilisez @JsonInclude:
@JsonInclude()
@Transient
private String token;
POINTE:
Vous pouvez également utiliser JsonInclude.Include.NON_NULL et masquer les champs dans JSON pendant la désérialisation lorsque token == null:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonIncluden'est pas nécessaire: les @Transientchamps sont toujours inclus dans JSON. (Vous avez quand même obtenu mon vote: la technique elle-même pourrait être très utile dans d'autres circonstances).
Pour ignorer un champ, annotez-le avec @Transientafin qu'il ne soit pas mappé en hibernation.
Source: Hibernate Annotations .
Cette réponse arrive un peu tard, mais elle complète la réponse.
Afin d'éviter qu'un champ d'une entité ne persiste dans la base de données, on peut utiliser l'un des deux mécanismes:
@Transient - l'annotation JPA marquant un champ comme non persistant
mot-clé transitoire en java. Attention - l'utilisation de ce mot-clé empêchera le champ d'être utilisé avec tout mécanisme de sérialisation de java. Donc, si le champ doit être sérialisé, vous feriez mieux d'utiliser uniquement l'annotation @Transient .
Il existe plusieurs solutions selon le type d'attribut d'entité.
Considérez que vous avez le accounttableau suivant :
Le accounttableau est mappé à l' Accountentité comme ceci:
@Entity(name = "Account")
public class Account {
@Id
private Long id;
@ManyToOne
private User owner;
private String iban;
private long cents;
private double interestRate;
private Timestamp createdOn;
@Transient
private double dollars;
@Transient
private long interestCents;
@Transient
private double interestDollars;
@PostLoad
private void postLoad() {
this.dollars = cents / 100D;
long months = createdOn.toLocalDateTime()
.until(LocalDateTime.now(), ChronoUnit.MONTHS);
double interestUnrounded = ( ( interestRate / 100D ) * cents * months ) / 12;
this.interestCents = BigDecimal.valueOf(interestUnrounded)
.setScale(0, BigDecimal.ROUND_HALF_EVEN).longValue();
this.interestDollars = interestCents / 100D;
}
//Getters and setters omitted for brevity
}
Les attributs des entités de base sont mis en correspondance avec des colonnes de table, donc des propriétés telles que id, iban, centssont des attributs de base.
Mais dollars, interestCentset interestDollarssont des propriétés calculées, afin que vous les annoter avec @Transientles exclure de SELECT, INSERT, UPDATE et DELETE SQL.
Ainsi, pour les attributs de base, vous devez utiliser
@Transientafin d'exclure une propriété donnée de la persistance.Pour plus de détails sur les attributs d'entité calculés, consultez cet article .
En supposant que vous disposez des éléments suivants postet des post_commenttableaux:
Vous souhaitez mapper l' lastestCommentassociation dans l' Postentité à la dernière PostCommententité ajoutée.
Pour ce faire, vous pouvez utiliser l' @JoinFormulaannotation:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(" +
"SELECT pc.id " +
"FROM post_comment pc " +
"WHERE pc.post_id = id " +
"ORDER BY pc.created_on DESC " +
"LIMIT 1" +
")")
private PostComment latestComment;
//Getters and setters omitted for brevity
}
Lors de la récupération de l' Postentité, vous pouvez voir que le latestCommentest récupéré, mais si vous souhaitez le modifier, le changement va être ignoré.
Ainsi, pour les associations, vous pouvez utiliser
@JoinFormulapour ignorer les opérations d'écriture tout en autorisant la lecture de l'association.Pour plus de détails sur les associations calculées, consultez cet article .
Une autre façon d'ignorer les associations déjà mappées par l'identifiant d'entité est d'utiliser @MapsId.
Par exemple, considérez la relation de table un-à-un suivante:
L' PostDetailsentité est mappée comme ceci:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Post post;
public PostDetails() {}
public PostDetails(String createdBy) {
createdOn = new Date();
this.createdBy = createdBy;
}
//Getters and setters omitted for brevity
}
Notez que l' idattribut et l' postassociation mappent la même colonne de base de données, qui est la post_detailscolonne Clé primaire.
Pour exclure l' idattribut, l' @MapsIdannotation indiquera à Hibernate que l' postassociation prend en charge la valeur de la colonne Clé primaire de la table.
Ainsi, lorsque l'identifiant d'entité et une association partagent la même colonne, vous pouvez utiliser
@MapsIdpour ignorer l'attribut d'identifiant d'entité et utiliser l'association à la place.Pour plus de détails sur
@MapsId, consultez cet article .
insertable = false, updatable = falseUne autre option consiste à utiliser insertable = false, updatable = falsepour l'association que vous souhaitez ignorer par Hibernate.
Par exemple, nous pouvons mapper l'association biunivoque précédente comme ceci:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
@Column(name = "post_id")
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne
@JoinColumn(name = "post_id", insertable = false, updatable = false)
private Post post;
//Getters and setters omitted for brevity
public void setPost(Post post) {
this.post = post;
if (post != null) {
this.id = post.getId();
}
}
}
Les attributs insertableet updatablede l' @JoinColumnannotation indiqueront à Hibernate d'ignorer l' postassociation car l'identifiant d'entité prend en charge la post_idcolonne Clé primaire.
postet post_detailscomme exemple?
Aucune des réponses ci-dessus n'a fonctionné pour moi en utilisant Hibernate 5.2.10, Jersey 2.25.1 et Jackson 2.8.9. J'ai finalement trouvé la réponse (en quelque sorte, ils font référence à hibernate4module mais cela fonctionne aussi pour 5) ici . Aucune des annotations Json n'a fonctionné du tout @Transient. Apparemment, Jackson2 est suffisamment «intelligent» pour ignorer les choses marquées par, à @Transientmoins que vous ne le lui disiez explicitement. La clé était d'ajouter le module hibernate5 (que j'utilisais pour gérer d'autres annotations Hibernate) et de désactiver la USE_TRANSIENT_ANNOTATIONfonctionnalité dans mon application Jersey:
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Voici la dépendance du Hibernate5Module:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.8.9</version>
</dependency>
@JsonProperty @JsonInclude @JsonSerialize + @JsonDeserialize mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false));cette solution a finalement fonctionné. Merci!