What's the difference between @Basic(optional = false)
and @Column(nullable = false)
in JPA persistence?
-
1duplicate http://stackoverflow.com/questions/1383229/java-persistence-jpa-column-vs-basic – Schildmeijer May 24 '10 at 18:15
-
15Not really a duplicate, the question is more about the attributes, not the annotations. – Pascal Thivent May 24 '10 at 19:47
-
May be it help more https://stackoverflow.com/a/59497054/6191407 – Sonu patel Dec 27 '19 at 07:58
2 Answers
Gordon Yorke (EclipseLink Architecture Committee Member, TopLink Core Technical Lead, JPA 2.0 Expert Group Member) wrote a good answer on this topic so instead of paraphrasing him, I'll quote his answer:
The difference between
optional
andnullable
is the scope at which they are evaluated. The definition of 'optional
' talks about property and field values and suggests that this feature should be evaluated within the runtime. 'nullable
' is only in reference to database columns.If an implementation chooses to implement
optional
then those properties should be evaluated in memory by the Persistence Provider and an exception raised before SQL is sent to the database otherwise when using 'updatable=false
' 'optional
' violations would never be reported.

- 562,542
- 136
- 1,062
- 1,124
-
8
-
41@Xie Jilei: From book: Java persistence with hibernate 2007, p. 179: `@Basic(optional = false) @Column(nullable = false)` The @Basic annotation marks the property as not optional on the Java object level. The second setting, nullable = false on the column mapping, is only responsible for the generation of a NOT NULL database constraint. The Hibernate JPA implementation treats both options the same way in any case, so you may as well use only one of the annotations for this purpose. – rapt Oct 26 '11 at 00:56
-
2@rapt - I don't understand `The @Basic annotation marks the property as not optional on the Java object level.` What does that mean ? So, only `@Basic` is like saying that make the database column `NOT NULL` for said variable ? – Erran Morad May 10 '14 at 00:12
-
13It means, if you try to persist an entity with a null field it will throw an exception if it is marked as optional=false (without contacting the database) and the entity will not be added to the JPA persistence context. If it is only annotated to be nullable=false the entity will be added to the persistence context and when trying to write the entity to the database (for example via flush) it will try to write the entity to the database which will deny this and it will throw an exception then. – Ray Hulha Aug 24 '15 at 16:16
-
@RayHulha I tried to annotate a field with "@Basic(optional=false)", and I added a tuple to the database (with the value of this field = null), no exception was raised!!, I hope you can explain to me this behavior. – ziMtyth Aug 20 '17 at 13:59
-
I tried it myself now that you had this issue and you are correct. The optional parameter to the Basic annotation is ignored. See my full answer for more details. – Ray Hulha Aug 21 '17 at 16:15
-
So I tried the @Basic(optional=false) annotation using JPA 2.1 (EclipseLink) and it turns out the annotation is ignored in actual usage (at least for a String field). (e.g. entityManager.persist calls).
So I went to the specification and read up about it.
Here is what the spec has to say:
http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-oth-JSpec/
Basic(optional): Whether the value of the field or property may be null. This is a hint and is disregarded for primitive types; it may be used in schema generation.
So I think this sentence explains the real use case for Basic(optional) it is used in schema generation. (That is: when you generate CREATE TABLE SQL from Java Entity classes. This is something Hibernate can do for example.)

- 10,701
- 5
- 53
- 53
-
1It's funny that the other answer implies that's nullable and not Basic that's used for schema generation (when it says «'nullable' is only in reference to database columns»). It's still very confusing. I guess nullable **is** used for schema generation and Basic(optional = false) **may** be used for the same purpose? Does that make sense? – marcus Oct 03 '18 at 15:26
-
`optional = false` is only for checking this constraint in runtime. `nullable = false` creates database constraint. For applications, to also set `optional = false` makes sense, because it is evaluated faster than going to database and check that constraint there.. – nimo23 May 24 '19 at 08:25