Wie mache ich eine Entität schreibgeschützt?

Lesezeit: 4 Minuten

Benutzer-Avatar
glmxndr

Was ist der richtige Weg, um eine Entität mit JPA schreibgeschützt zu machen? Ich möchte, dass meine Datenbanktabelle niemals programmgesteuert geändert wird.

Ich glaube, ich verstehe, dass ich meine Objekte mit sperren sollte LockModeType.READ. Ist es möglich, eine Anmerkung zu verwenden, um meine Entitäten direkt nach dem Abrufen aus der Datenbank zu sperren? Oder muss ich herumspielen und mein generisches DAO für diese bestimmte Entität überschreiben?

Benutzer-Avatar
slartidan

Fügen Sie in Ihrer Entität eine hinzu EntityListener so was:

@Entity
@EntityListeners(PreventAnyUpdate.class)
public class YourEntity {
    // ...
}

Implementieren Sie Ihre EntityListenerum eine Ausnahme auszulösen, wenn ein Update auftritt:

public class PreventAnyUpdate {

    @PrePersist
    void onPrePersist(Object o) {
        throw new IllegalStateException("JPA is trying to persist an entity of type " + (o == null ? "null" : o.getClass()));
    }

    @PreUpdate
    void onPreUpdate(Object o) {
        throw new IllegalStateException("JPA is trying to update an entity of type " + (o == null ? "null" : o.getClass()));
    }

    @PreRemove
    void onPreRemove(Object o) {
        throw new IllegalStateException("JPA is trying to remove an entity of type " + (o == null ? "null" : o.getClass()));
    }
}

Dadurch wird mit JPA-Lifecycle-Listenern ein kugelsicheres Sicherheitsnetz für Ihr Unternehmen geschaffen.

  • PRO: JPA-Standard – nicht spezifisch für den Ruhezustand
  • PRO: sehr sicher
  • CON: Zeigt nur Schreibversuche an Laufzeit. Wenn Sie möchten Kompilierzeit überprüfen, sollten Sie keine Setter implementieren.

  • Ich sehe das ein paar Jahre später, und es ist immer noch eine großartige Lösung. 🙂

    – drognisep

    6. März 2020 um 21:19 Uhr

Benutzer-Avatar
Nikolaus

Eine Lösung besteht darin, feldbasierte Anmerkungen zu verwenden, um Ihre Felder als zu deklarieren protected und nur öffentlichen Getter vorzuschlagen. Dabei können Ihre Objekte nicht verändert werden.

(Diese Lösung ist nicht objektspezifisch, sondern nur eine Möglichkeit, unveränderliche Objekte zu erstellen.)

  • Sie haben vergessen: “und stellen Sie sicher, dass die Getter nur unveränderliche Werte zurückgeben”. zB Sammlungsfelder

    – Daniel Alexiuc

    15. August 2011 um 3:36 Uhr

  • Was bedeutet feldbasierte Annotation?

    – Willkommen zu

    15. Februar 2013 um 14:42 Uhr

  • Es funktioniert, aber ich hasse es. Macht das Testen unnötig schwer, da Sie sich etwas einfallen lassen müssen, um die Kapselung zu brechen. Ich schlage eine benutzerdefinierte Anmerkung vor, die eine Ausnahme verursacht, wenn eine Setter-Methode aufgerufen wird und kein Testframework erkannt wird. Diese Anmerkung würde in Ihrer IDE auch wie @Deprecated aussehen. Alternativ könnten Sie eine Anmerkung als Erweiterung Ihres bevorzugten Testframeworks schreiben.

    – Benutzer447607

    19. September 2013 um 17:59 Uhr

  • Sie sollten private statt protected verwenden. Wenn Sie es schützen, können Sie immer noch von anderen Klassen im selben Paket auf die Eigenschaft zugreifen. Faustregel: Instanzvariablen sind immer privat.

    – Jordan Silva

    11. November 2015 um 8:34 Uhr

  • Mit diesem Ansatz können Sie immer noch neue Entitäten hinzufügen (INSERT)

    – Andy

    19. Dezember 2017 um 22:40 Uhr

Benutzer-Avatar
Tobi Artisan

Hibernate hat auch eine org.hibernate.annotations.Immutable Anmerkung, die Sie dem Typ, der Methode oder dem Feld hinzufügen können.

  • Sei vorsichtig mit @Immutable. Es ist nicht sehr hilfreich. Wenn Sie versuchen zu aktualisieren, wird es keinen Fehler geben: es wird nur stillschweigend scheitern. Aus der Hibernate-Dokumentation: “Updates an einer unveränderlichen Entität werden ignoriert, aber es wird keine Ausnahme ausgelöst”.

    – David Lavendel

    11. August 2015 um 15:11 Uhr

  • Sie können die Entität auch mit @Immutable kommentieren. In unserem Fall war ein stiller Fehler das, was wir brauchten, da wir bestimmte Entitäten aktualisieren wollten, andere jedoch nicht, die stattdessen mithilfe gespeicherter Prozeduren aktualisiert werden sollten.

    – Kt. Mack

    8. September 2017 um 15:07 Uhr

Wenn sich Ihre JPA-Implementierung im Ruhezustand befindet, können Sie die Hibernate-Entity-Anmerkung verwenden

@org.hibernate.annotations.Entity(mutable = false)

Offensichtlich wird dies Ihr Modell jedoch in den Ruhezustand versetzen.

Benutzer-Avatar
Mac

IIRC, auf das Sie jedes Feld einstellen könnten insertable = false und updatable = false in deiner @Column Anmerkungen, aber ich bin sicher, es muss eine bessere Methode geben … 🙂

Ich vermute nicht Dies hilft?

Benutzer-Avatar
Timmo

Ich denke, wonach Sie suchen, ist, dass Ihr Wesen unveränderlich ist. Hibernate unterstützt dies; JPA (mindestens JPA 1.0) nicht. Ich nehme an, Sie können dies nur steuern, indem Sie nur Getter bereitstellen und sicherstellen, dass die Getter nur unveränderliche Werte zurückgeben.

Benutzer-Avatar
rzymek

Die Eclipselink-Implementierung bietet Ihnen auch die @ReadOnly Anmerkung auf Entitätsebene

  • wo ist die referenz, die ich jetzt im juni 2016 nicht finden konnte

    – Shareef

    8. August 2016 um 7:22 Uhr

1258070cookie-checkWie mache ich eine Entität schreibgeschützt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy