@ Basic (可选 = false) vs@Column (nullable = false) in JPA

@Basic(optional = false)@Column(nullable = false)在 JPA 持久性方面有什么不同?

58909 次浏览

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 and nullable 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.

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.)