Risposte:
@Transient
conforme alle tue esigenze.
Per ignorare un campo, annotalo in @Transient
modo 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;
@JsonInclude
non è necessario: i @Transient
campi 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 @Transient
modo 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 account
tabella:
La account
tabella è mappata Account
all'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
, cents
sono attributi di base.
Ma la dollars
, interestCents
e interestDollars
vengono calcolati proprietà, in modo da poterli annotare con @Transient
escluderle dal SELECT, INSERT, UPDATE e DELETE istruzioni SQL.
Pertanto, per gli attributi di base, è necessario utilizzare
@Transient
per escludere la persistenza di una determinata proprietà.Per ulteriori dettagli sugli attributi di entità calcolati, consulta questo articolo .
Supponendo di avere quanto segue post
e le post_comment
tabelle:
Si desidera mappare l' lastestComment
associazione Post
nell'entità all'ultima PostComment
entità che è stata aggiunta.
Per fare ciò, puoi usare l' @JoinFormula
annotazione:
@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' Post
entità, puoi vedere che latestComment
è stata recuperata, ma se vuoi modificarla, la modifica verrà ignorata.
Pertanto, per le associazioni, è possibile utilizzare
@JoinFormula
per 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' PostDetails
entità è 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' id
attributo che l' post
associazione mappano la stessa colonna del database, che è la post_details
colonna Chiave primaria.
Per escludere l' id
attributo, l' @MapsId
annotazione dirà a Hibernate che l' post
associazione 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
@MapsId
per ignorare l'attributo identificatore di entità e utilizzare invece l'associazione.Per maggiori dettagli
@MapsId
, consulta questo articolo .
insertable = false, updatable = false
Un'altra opzione è utilizzare insertable = false, updatable = false
per 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 insertable
e dell'annotazione indicano a Hibernate di ignorare l' associazione poiché l'identificatore di entità si occupa della colonna Chiave primaria.updatable
@JoinColumn
post
post_id
post
e post_details
tabelle 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 @Transient
meno 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_ANNOTATION
funzione 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!