Reputation: 3152
In our application, we need to have fields that are assignable only once.
At first we thought of encapsulating the fields and making the setters private. However, some questions arouse:
Thanks in advance.
Upvotes: 23
Views: 16807
Reputation: 345
Try
@Column(updatable = false)
And make your setter private. (Leave your getter public if you want)
I think this is the best practice.
P.S.: JPA uses field access if you annotate your fields and uses getter/setter access if you annotate your getter method.
Upvotes: 18
Reputation: 641
Try
@Column(updatable = false)
From javadoc:
Whether the column is included in SQL UPDATE statements generated by the persistence provider.
Upvotes: 4
Reputation: 1409
You can mark an entity with @Entity(mutable=false)
or @Immutable
annotations for the framework to make use of this fact for performance gain in caching and such. (Hibernate)
Then you can use an immutable wrapper class like this:
public class ImmutableStuff {
private final FooField barValue;
public ImmutableStuff(Stuff stuff) {
barValue = stuff.barValue;
}
public FooField getBarValue(){
return barValue;
}
}
Upvotes: 1
Reputation: 340863
Ad. 1: I believe JPA uses plain private fields for both read and write if annotations are placed on fields and not on getters. Recently I discovered that Hibernate as an underlying JPA provider does not even need get*()
and set*()
methods at all. This was truly enlightening solution since from the beginning I thought Hibernate needs accessors. So the answer is: you don't need setters as far as Hibernate is concerned.
Ad. 2: However please note that Hibernate still needs no-arg constructor, otherwise it will fail to load entities with a descriptive exception. This is also a JPA requirement.
Ad. 3: No, there isn't. Remember that your collections would also had to be immutable.
Upvotes: 16
Reputation: 18194
In JPA 2.0 you have two ways to define what attributes should be persisted:
If no Access(-) annotation is used, the decision what access will be used depends on where you put your @Id annotation. If you put it next to your field - Access(FIELD) will be used. If you put it next to your accessor - Access(PROPERTY) will be used.
Therefore, if you use Access(FIELD) you don't have to have an appropriate JavaBeans-style accessor for particular field. You can have a private field named 'myField' and a public setter for it named 'public setBlahBlah(-)'. The JPA will persist just the 'myField'.
Upvotes: 3