Antworten:
@Transient entspricht Ihren Bedürfnissen.
Um ein Feld zu ignorieren, kommentieren Sie es mit, @Transientdamit es nicht im Ruhezustand zugeordnet wird.
Aber dann serialisiert Jackson das Feld bei der Konvertierung in JSON nicht.
Wenn Sie JPA mit JSON mischen müssen (von JPA weglassen, aber immer noch in Jackson enthalten), verwenden Sie @JsonInclude:
@JsonInclude()
@Transient
private String token;
TRINKGELD:
Sie können auch JsonInclude.Include.NON_NULL verwenden und Felder in JSON während der Deserialisierung ausblenden, wenn token == null:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonIncludeist dies nicht erforderlich: @TransientFelder sind weiterhin in JSON enthalten. (Sie haben immer noch meine Stimme erhalten: Die Technik selbst könnte unter anderen Umständen sehr nützlich sein).
Um ein Feld zu ignorieren, kommentieren Sie es mit, @Transientdamit es nicht im Ruhezustand zugeordnet wird.
Quelle: Anmerkungen zum Ruhezustand .
Diese Antwort kommt etwas spät, vervollständigt aber die Antwort.
Um zu vermeiden, dass ein Feld einer Entität in der Datenbank beibehalten wird, kann einer der beiden Mechanismen verwendet werden:
@Transient - Die JPA-Annotation, die ein Feld als nicht dauerhaft markiert
vorübergehendes Schlüsselwort in Java. Achtung: Wenn Sie dieses Schlüsselwort verwenden, wird verhindert, dass das Feld mit einem Serialisierungsmechanismus von Java verwendet wird. Wenn das Feld also serialisiert werden muss, verwenden Sie besser nur dieAnnotation @Transient .
Abhängig vom Entitätsattributtyp gibt es mehrere Lösungen.
Angenommen, Sie haben die folgende accountTabelle:
Die accountTabelle wird der AccountEntität wie folgt zugeordnet :
@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
}
Die Grundeinheit Attribute werden in Tabellenspalten zugeordnet, so Eigenschaften wie id, iban, centssind grundlegende Attribute.
Aber die dollars, interestCentsund interestDollarsEigenschaften berechnet werden , so dass Sie sie mit Anmerkungen versehen mit @Transientauszuschließen sie von SELECT, INSERT, UPDATE und DELETE SQL - Anweisungen.
Für grundlegende Attribute müssen Sie also verwenden
@Transient, um eine bestimmte Eigenschaft vom Fortbestehen auszuschließen.Weitere Informationen zu berechneten Entitätsattributen finden Sie in diesem Artikel .
Angenommen, Sie haben Folgendes postund post_commentTabellen:
Sie möchten die lastestCommentZuordnung in der PostEntität der zuletzt PostCommenthinzugefügten Entität zuordnen.
Dazu können Sie die @JoinFormulaAnmerkung verwenden:
@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
}
Beim Abrufen der PostEntität können Sie sehen, dass die Entität latestCommentabgerufen wird. Wenn Sie sie jedoch ändern möchten, wird die Änderung ignoriert.
Bei Zuordnungen können Sie also
@JoinFormuladie Schreibvorgänge ignorieren, während Sie das Lesen der Zuordnung weiterhin zulassen.Weitere Informationen zu berechneten Zuordnungen finden Sie in diesem Artikel .
Eine andere Möglichkeit, Assoziationen zu ignorieren, die bereits von der Entitätskennung zugeordnet wurden, ist die Verwendung @MapsId.
Betrachten Sie beispielsweise die folgende Eins-zu-Eins-Tabellenbeziehung:
Die PostDetailsEntität wird wie folgt zugeordnet:
@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
}
Beachten Sie, dass sowohl das idAttribut als auch die postZuordnung dieselbe Datenbankspalte zuordnen, die die post_detailsPrimärschlüsselspalte ist.
Um das idAttribut auszuschließen , @MapsIdteilt die Annotation Hibernate mit, dass sich die postZuordnung um den Spaltenwert der Tabelle Primärschlüssel kümmert.
Wenn also die Entitätskennung und eine Zuordnung dieselbe Spalte verwenden, können Sie
@MapsIddas Entitätskennungsattribut ignorieren und stattdessen die Zuordnung verwenden.Weitere Informationen zu
@MapsIdfinden Sie in diesem Artikel .
insertable = false, updatable = falseEine andere Option ist die Verwendung insertable = false, updatable = falsefür die Zuordnung, die vom Ruhezustand ignoriert werden soll.
Zum Beispiel können wir die vorherige Eins-zu-Eins-Zuordnung wie folgt abbilden:
@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();
}
}
}
Die Attribute insertableund updatableder @JoinColumnAnnotation weisen Hibernate an, die postZuordnung zu ignorieren , da sich die Entitätskennung um die post_idSpalte Primärschlüssel kümmert .
postund post_detailsTabellen als Beispiel korrekt ?
Um die obigen Antworten zu vervollständigen, hatte ich den Fall, dass eine XML-Zuordnungsdatei verwendet wurde, in der weder die @Transientnoch transientfunktionierte ... Ich musste die vorübergehenden Informationen in die XML-Datei einfügen:
<attributes>
(...)
<transient name="field" />
</attributes>
Keine der oben genannten Antworten hat bei mir mit Hibernate 5.2.10, Jersey 2.25.1 und Jackson 2.8.9 funktioniert. Ich fand schließlich die Antwort ( eine Art Bezug sie hibernate4module aber es funktioniert für 5 auch) hier . Keine der Json-Anmerkungen funktionierte überhaupt mit @Transient. Anscheinend ist Jackson2 "klug" genug, um Dinge zu ignorieren, die mit gekennzeichnet sind, es @Transientsei denn, Sie sagen ausdrücklich, dass dies nicht der Fall ist . Der Schlüssel bestand darin, das Hibernate5-Modul hinzuzufügen (mit dem ich andere Hibernate-Anmerkungen bearbeitet habe) und die USE_TRANSIENT_ANNOTATIONFunktion in meiner Jersey-Anwendung zu deaktivieren :
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Hier ist die Abhängigkeit für das 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));funktionierte diese Lösung schließlich. Vielen Dank!
Manchmal möchten Sie:
Verwenden @Column(name = "columnName", insertable = false, updatable = false)
Ein gutes Szenario ist, wenn eine bestimmte Spalte automatisch unter Verwendung anderer Spaltenwerte berechnet wird