Is it possible to have immutable fields in Hibernate/JPA?

后端 未结 5 1554
清歌不尽
清歌不尽 2021-02-07 03:00

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 q

相关标签:
5条回答
  • 2021-02-07 03:29
    • 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.

    0 讨论(0)
  • 2021-02-07 03:37

    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.

    0 讨论(0)
  • 2021-02-07 03:41

    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;
        }
    }
    
    0 讨论(0)
  • 2021-02-07 03:44

    In JPA 2.0 you have two ways to define what attributes should be persisted:

    1. Access(FIELD) - the fields name are persisted,
    2. Access(PROPERTY) - the properties name are 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'.

    0 讨论(0)
  • 2021-02-07 03:47

    Try

    @Column(updatable = false)
    

    From javadoc:

    Whether the column is included in SQL UPDATE statements generated by the persistence provider.

    0 讨论(0)
提交回复
热议问题