In JPA, I am confused when to use the attribute optional=false
and the annotation @Column(nullable=false)
. What is the difference?
-
4possible dupe - http://stackoverflow.com/questions/2899073/basicoptional-false-vs-columnnullable-false-in-jpa i think the discussion there for @Basic(optional=false) applies as well to @ManyToOne(optional=false) – Dan LaRocque Jul 26 '10 at 02:40
2 Answers
@Column(nullable=false)
is an instruction for generating the schema. The database column generated off the class will be marked not nullable in the actual database.
optional=false
is a runtime instruction. The primary functional thing it does is related to Lazy Loading. You can't lazy load a non-collection mapped entity unless you remember to set optional=false (because Hibernate doesn't know if there should be a proxy there or a null, unless you tell it nulls are impossible, so it can generate a proxy.)

- 47,174
- 11
- 83
- 83
-
33Another interesting fact is that most persistence providers use the information given by the "optional" parameter to optimize the query at runtime. For instance when loading the entity. Thus all relations of the actual entity specified with optional=false result in an INNER JOIN to their respective relation when loaded, whereas relations specified with optional=true result in LEFT JOINs. – Lars Jan 25 '16 at 21:47
Both is used to prevent a null value, but if you mind that null should be blocked in ...
The database layer (and you want to generate the schema using JPA) --> use @Column(nullable=false)
The runtime (and before contacting the database)--> use optional=false
(much faster than the first checking).
If you want both abilities, use them both.

- 2,853
- 2
- 27
- 36
-
The runtime fact has already been addressed by Affe: "optional=false is a runtime instruction." – Kawu May 15 '17 at 12:47