How to make an Entity read-only?
What is the proper way to make an Entity read-only with JPA ? I wish my database table to never be modified at all programmatically.
I think I understand that I should lock my objects with LockModeType.READ
. Is it possible to use an annotation to make my entities directly locked after retrieval from the database ? Or do I have to mess around and override my generic DAO for that specific entity ?
Solution 1:
In your entity add an EntityListener
like this:
@Entity
@EntityListeners(PreventAnyUpdate.class)
public class YourEntity {
// ...
}
Implement your EntityListener
, to throw an exception if any update occurs:
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()));
}
}
This will create a bullet proof safety net for your entity with JPA lifecycle listeners.
- PRO: JPA standard - not hibernate specific
- PRO: very safe
- CON: only shows write attempts at runtime. If you want a compile time check, you should not implement setters.
Solution 2:
A solution is to use field based annotation, to declare your fields as protected
and to propose only public getter. Doing so, your objects can not be altered.
(This solution is not entity specific, it is just a way to build immutable objects)
Solution 3:
Hibernate also has a org.hibernate.annotations.Immutable
annotation that you can put on the type, method, or field.
Solution 4:
If your JPA implementation is hibernate - you could use the hibernate Entity annotation
@org.hibernate.annotations.Entity(mutable = false)
Obviously this will tie your model to hibernate though.