Ich bin im Wesentlichen auf der Suche nach einer Anmerkung vom Typ "@Ignore", mit der ich verhindern kann, dass ein bestimmtes Feld persistiert wird. Wie kann dies erreicht werden?
Antworten
Zu viele Anzeigen?@Transient
auf Ihre Bedürfnisse abgestimmt ist.
Um ein Feld zu ignorieren, vermerken Sie es mit @Transient
damit sie nicht von Hibernate abgebildet wird.
aber dann jackson lässt sich nicht serialisieren das Feld bei der Konvertierung in JSON.
Wenn Sie JPA mit JSON mischen müssen (von JPA weggelassen, aber in Jackson noch enthalten) verwenden @JsonInclude
:
@JsonInclude()
@Transient
private String token;
TIPP:
Sie können auch Folgendes verwenden JsonInclude.Include.NON_NULL und Felder in JSON während der Deserialisierung ausblenden, wenn token == null
:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
Um ein Feld zu ignorieren, vermerken Sie es mit @Transient
damit sie nicht von Hibernate abgebildet wird.
Quelle: Hibernate-Bemerkungen .
Diese Antwort kommt ein wenig spät, aber sie vervollständigt die Antwort.
Um zu vermeiden, dass ein Feld aus einer Entität in der DB persistiert wird, kann man einen der beiden Mechanismen verwenden:
@Transient - die JPA-Anmerkung, die ein Feld als nicht persistierbar kennzeichnet
transient Schlüsselwort in Java. Achtung - die Verwendung dieses Schlüsselworts verhindert, dass das Feld mit einem Serialisierungsmechanismus von Java verwendet werden kann. Wenn das Feld also serialisiert werden muss, verwenden Sie besser nur das @Transient Bemerkung.
Je nach Art des Entitätsattributs gibt es mehrere Lösungen.
Grundlegende Attribute
Nehmen wir an, Sie haben Folgendes account
Tisch:
En account
Tabelle wird auf die Tabelle Account
Einheit wie diese:
@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 grundlegenden Entitätsattribute werden auf Tabellenspalten abgebildet, so dass Eigenschaften wie id
, iban
, cents
sind grundlegende Attribute.
Aber die dollars
, interestCents
y interestDollars
sind berechnete Eigenschaften, daher werden sie mit @Transient
um sie von den SQL-Anweisungen SELECT, INSERT, UPDATE und DELETE auszuschließen.
Für grundlegende Attribute müssen Sie also
@Transient
um eine bestimmte Eigenschaft von der Persistenz auszuschließen.
Verbände
Angenommen, Sie haben Folgendes post
y post_comment
Tabellen:
Sie möchten die Karte latestComment
Verein im Post
Entität auf dem neuesten PostComment
Entität, die hinzugefügt wurde.
Zu diesem Zweck können Sie die @JoinFormula
Bemerkung:
@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 Post
Entität können Sie sehen, dass die latestComment
abgerufen, aber wenn Sie es ändern wollen, wird die Änderung ignoriert.
Für Assoziationen können Sie also verwenden
@JoinFormula
um die Schreibvorgänge zu ignorieren, aber dennoch das Lesen der Assoziation zu ermöglichen.
@MapsId
Eine andere Möglichkeit, Assoziationen zu ignorieren, die bereits durch den Entitätsidentifikator abgebildet sind, ist die Verwendung von @MapsId
.
Betrachten Sie zum Beispiel die folgende eins-zu-eins-Tabellenbeziehung:
En PostDetails
Entität wird wie folgt abgebildet:
@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 die id
post
Assoziation die gleiche Datenbankspalte abbilden, nämlich die post_details
Spalte Primärschlüssel.
Zum Ausschluss der id
Attribut, das @MapsId
Annotation teilt Hibernate mit, dass die post
Assoziation kümmert sich um den Wert der Primärschlüsselspalte der Tabelle.
Wenn also der Entitätsbezeichner und eine Assoziation dieselbe Spalte haben, können Sie
@MapsId
um das Attribut "Entity Identifier" zu ignorieren und stattdessen die Assoziation zu verwenden.
Verwendung von insertable = false, updatable = false
Eine weitere Möglichkeit ist die Verwendung von insertable = false, updatable = false
für die Assoziation, die von Hibernate ignoriert werden soll.
Wir können zum Beispiel die vorherige Eins-zu-Eins-Assoziation 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();
}
}
}
En insertable
y updatable
Attribute der @JoinColumn
Annotation weist Hibernate an, die post
Assoziation, da der Entity Identifier für die post_id
Spalte Primärschlüssel.
- See previous answers
- Weitere Antworten anzeigen