Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an Entity read-only?

Tags:

java

jpa

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 ?

like image 336
glmxndr Avatar asked Feb 25 '11 09:02

glmxndr


People also ask

How to make entity read only in java?

Read Only Entity with Criteria.setReadOnly(true) to make entities read-only.

What is @transactional readOnly true?

If we use @Transactional(readOnly = true) to a method which is performing create or update operation then we will not have newly created or updated record into the database but we will have the response data.

Why is it best practice to mark transactions as read only?

Transactions indeed put locks on the database — good database engines handle concurrent locks in a sensible way — and are useful with read-only use to ensure that no other transaction adds data that makes your view inconsistent.

Can we have entity without ID?

Like the text says: an entity must have an identifier to allow relationships. No identifier, no relationships. To be clear: If Customer has no id, it can still reference other entities. But it can't be referenced by others.


1 Answers

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.
like image 96
slartidan Avatar answered Sep 28 '22 04:09

slartidan