Comment faire une entité en lecture seule?

Quelle est la bonne façon de rendre une entité en lecture seule avec JPA? Je souhaite que ma table de firebase database ne soit jamais modifiée du tout par programmation.

Je pense que je comprends que je devrais verrouiller mes objects avec LockModeType.READ . Est-il possible d’utiliser une annotation pour rendre mes entités directement verrouillées après la récupération de la firebase database? Ou est-ce que je dois bricoler et remplacer mon DAO générique pour cette entité spécifique?

Une solution consiste à utiliser des annotations basées sur des champs, à déclarer vos champs comme protected et à ne proposer que des getter publics. Ce faisant, vos objects ne peuvent pas être modifiés.

(Cette solution n’est pas spécifique à une entité, c’est juste un moyen de créer des objects immuables)

Vous pouvez créer un filet de sécurité pare-balles pour votre entité avec les écouteurs de cycle de vie JPA.

  • PRO: norme JPA – pas d’hibernation spécifique
  • PRO: très sûr
  • CON: affiche uniquement les tentatives d’écriture à l’ exécution . Si vous souhaitez une vérification du temps de compilation , vous ne devez pas implémenter de parameters.

Dans votre entité, ajoutez un EntityListener comme ceci:

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

Implémentez votre EntityListener , pour lancer une exception en cas de mise à jour:

 public class PreventAnyUpdate { @PrePersist void onPrePersist(Object o) { throw new RuntimeException("..."); } @PreUpdate void onPreUpdate(Object o) { throw new RuntimeException("..."); } @PreRemove void onPreRemove(Object o) { throw new RuntimeException("..."); } } 

Si votre implémentation JPA est en veille prolongée, vous pouvez utiliser l’annotation Hibernate Entity

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

Évidemment, cela mettra votre modèle en veille prolongée.

Hibernate a également une annotation org.hibernate.annotations.Immutable que vous pouvez mettre sur le type, la méthode ou le champ.

Je pense que ce que vous recherchez est que votre entité soit immuable. Hibernate soutient cela; JPA (au moins JPA 1.0) ne le fait pas. Je suppose que vous ne pouvez contrôler cela qu’en fournissant seulement des indicateurs et en vous assurant que les getters ne renvoient que des valeurs immuables.

IIRC vous pouvez définir chaque champ sur updatable = false insertable = false et updatable = false dans vos annotations @Column , mais je suis sûr qu’il doit y avoir une meilleure méthode … 🙂

Je ne pense pas que cela aide?

L’implémentation d’Eclipselink vous offre également l’annotation @ReadOnly au niveau de l’entité

Cela va probablement me prendre un coup de main parce que je suis toujours sous-estimé pour le suggérer, mais vous pouvez utiliser AspectJ de plusieurs manières pour le faire respecter:

Soit automatiser la solution de Mac (faire en sorte que AspectJ injecte l’annotation @Column ):

 declare @field : (@Entity *) *.* : @Column(insertable=false); 

Ou déclarez une erreur de compilation pour tous les access aux méthodes set:

 declare error : execution((@Entity *) *.set*(*) ); 

Inconvénient: vous devez append la compilation AspectJ à votre build, mais c’est facile si vous utilisez ant ou maven

Si vous utilisez des données Spring ou utilisez le modèle Repository, n’incluez aucune méthode save / update / create / insert / etc dans le Repository pour cette entité particulière. Cela peut être généralisé en ayant une classe / interface de base pour les entités en lecture seule, et une classe pouvant être mise à jour qui étend celle en lecture seule pour les entités pouvant être mises à jour. Comme d’autres affiches l’ont fait remarquer, les créateurs peuvent également être rendus non publics pour éviter que les développeurs définissent accidentellement des valeurs qu’ils ne peuvent alors pas enregistrer.