Risposte:
@Transient conforme alle tue esigenze.
Per ignorare un campo, annotalo in @Transientmodo che non venga mappato dall'ibernazione.
ma poi jackson non serializzerà il campo durante la conversione in JSON.
Se hai bisogno di mescolare JPA con JSON (ometti da JPA ma includi ancora in Jackson) usa @JsonInclude:
@JsonInclude()
@Transient
private String token;
MANCIA:
Puoi anche usare JsonInclude.Include.NON_NULL e nascondere i campi in JSON durante la deserializzazione quando token == null:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonIncludenon è necessario: i @Transientcampi sono ancora inclusi in JSON. (Hai ancora ottenuto il mio voto: la tecnica stessa potrebbe essere molto utile in altre circostanze).
Per ignorare un campo, annotalo in @Transientmodo che non venga mappato dall'ibernazione.
Fonte: Hibernate Annotations .
Questa risposta arriva un po 'in ritardo, ma completa la risposta.
Per evitare che un campo di un'entità sia persistente nel DB, è possibile utilizzare uno dei due meccanismi:
@Transient : l'annotazione JPA che contrassegna un campo come non persistente
parola chiave transitoria in Java. Attenzione: utilizzando questa parola chiave, il campo non verrà utilizzato con alcun meccanismo di serializzazione da Java. Quindi, se il campo deve essere serializzato, è meglio usare solo l'annotazione @Transient .
Esistono più soluzioni a seconda del tipo di attributo dell'entità.
Considera di avere la seguente accounttabella:
La accounttabella è mappata Accountall'entità in questo modo:
@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
}
Gli attributi di base dell'entità sono mappati colonne della tabella, così immobili come id, iban, centssono attributi di base.
Ma la dollars, interestCentse interestDollarsvengono calcolati proprietà, in modo da poterli annotare con @Transientescluderle dal SELECT, INSERT, UPDATE e DELETE istruzioni SQL.
Pertanto, per gli attributi di base, è necessario utilizzare
@Transientper escludere la persistenza di una determinata proprietà.Per ulteriori dettagli sugli attributi di entità calcolati, consulta questo articolo .
Supponendo di avere quanto segue poste le post_commenttabelle:
Si desidera mappare l' lastestCommentassociazione Postnell'entità all'ultima PostCommententità che è stata aggiunta.
Per fare ciò, puoi usare l' @JoinFormulaannotazione:
@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
}
Quando recuperi l' Postentità, puoi vedere che latestCommentè stata recuperata, ma se vuoi modificarla, la modifica verrà ignorata.
Pertanto, per le associazioni, è possibile utilizzare
@JoinFormulaper ignorare le operazioni di scrittura pur consentendo la lettura dell'associazione.Per maggiori dettagli sulle associazioni calcolate, consulta questo articolo .
Un altro modo per ignorare le associazioni che sono già mappate dall'identificatore di entità è usare @MapsId.
Ad esempio, considera la seguente relazione di tabella uno a uno:
L' PostDetailsentità è mappata in questo modo:
@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
}
Si noti che sia l' idattributo che l' postassociazione mappano la stessa colonna del database, che è la post_detailscolonna Chiave primaria.
Per escludere l' idattributo, l' @MapsIdannotazione dirà a Hibernate che l' postassociazione si occupa del valore della colonna Chiave primaria della tabella.
Pertanto, quando l'identificatore di entità e un'associazione condividono la stessa colonna, è possibile utilizzare
@MapsIdper ignorare l'attributo identificatore di entità e utilizzare invece l'associazione.Per maggiori dettagli
@MapsId, consulta questo articolo .
insertable = false, updatable = falseUn'altra opzione è utilizzare insertable = false, updatable = falseper l'associazione che si desidera venga ignorata da Hibernate.
Ad esempio, possiamo mappare la precedente associazione one-to-one in questo modo:
@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();
}
}
}
Gli attributi insertablee dell'annotazione indicano a Hibernate di ignorare l' associazione poiché l'identificatore di entità si occupa della colonna Chiave primaria.updatable@JoinColumnpostpost_id
poste post_detailstabelle come esempio?
Nessuna delle risposte di cui sopra ha funzionato per me usando Hibernate 5.2.10, Jersey 2.25.1 e Jackson 2.8.9. Ho finalmente trovato la risposta (in qualche modo, fanno riferimento a hibernate4module ma funziona anche per 5) qui . Nessuna delle annotazioni Json ha funzionato affatto @Transient. A quanto pare Jackson2 è abbastanza 'intelligente' da ignorare gentilmente le cose contrassegnate con a @Transientmeno che non gli dica esplicitamente di non farlo. La chiave era aggiungere il modulo hibernate5 (che stavo usando per gestire altre annotazioni Hibernate) e disabilitare la USE_TRANSIENT_ANNOTATIONfunzione nella mia applicazione Jersey:
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Ecco la dipendenza per il modulo Hibernate5:
<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));questa soluzione ha finalmente funzionato. Grazie!