351 Stimmen

Wie lässt sich ein JPA-Feld während der Persistenz am einfachsten ignorieren?

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?

538voto

cletus Punkte 596503

@Transient auf Ihre Bedürfnisse abgestimmt ist.

173voto

Kamil Nękanowicz Punkte 5586

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;

28voto

Jonathan Punkte 281

Um ein Feld zu ignorieren, vermerken Sie es mit @Transient damit sie nicht von Hibernate abgebildet wird.
Quelle: Hibernate-Bemerkungen .

22voto

Olimpiu POP Punkte 4836

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.

13voto

Vlad Mihalcea Punkte 121171

Je nach Art des Entitätsattributs gibt es mehrere Lösungen.

Grundlegende Attribute

Nehmen wir an, Sie haben Folgendes account Tisch:

The account table

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:

The post and post_comment tables

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:

The post and post_details tables

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X