@Basic (необязательно = false) против @Column (nullable = false) в JPA

103

В чем разница между сохранением JPA @Basic(optional = false)и @Column(nullable = false)в нем?

Joaosavio
источник
1
дубликат stackoverflow.com/questions/1383229/…
Шильдмейер,
14
Не совсем дубликат, вопрос скорее в атрибутах, а не в аннотациях.
Паскаль Тивент,
Может быть, это поможет больше stackoverflow.com/a/59497054/6191407
Сону

Ответы:

98

Гордон Йорк (член комитета по архитектуре EclipseLink, технический руководитель TopLink Core, член экспертной группы JPA 2.0) написал хороший ответ на эту тему, поэтому вместо того, чтобы перефразировать его, я процитирую его ответ :

Разница между optionalи nullableзаключается в объеме, в котором они оцениваются. Определение " optional" говорит о значениях свойств и полей и предполагает, что эту функцию следует оценивать во время выполнения. ' nullable' относится только к столбцам базы данных.

Если реализация решает реализовать, optionalтогда эти свойства должны быть оценены в памяти поставщиком сохраняемости, и перед отправкой SQL в базу данных должно возникать исключение, в противном случае при использовании ' updatable=false' ' optional' нарушения никогда не будут сообщаться.

Паскаль Тивент
источник
8
Итак, что на самом деле следует использовать, может быть, и то, и другое?
Xiè Jìléi
39
@Xie Jilei: Из книги: Сохранение Java в спящем режиме 2007, стр. 179: @Basic(optional = false) @Column(nullable = false)аннотация @Basic отмечает свойство как необязательное на уровне объекта Java. Второй параметр, nullable = false в сопоставлении столбцов, отвечает только за создание ограничения базы данных NOT NULL. Реализация Hibernate JPA в любом случае обрабатывает оба параметра одинаково, поэтому вы также можете использовать для этой цели только одну из аннотаций.
рапт
2
@rapt - я не понимаю, The @Basic annotation marks the property as not optional on the Java object level.что это значит? Итак, @Basicэто все равно что сказать, что сделать столбец базы данных NOT NULLдля указанной переменной?
Эрран Морад
9
Это означает, что если вы попытаетесь сохранить сущность с пустым полем, она выдаст исключение, если она помечена как optional = false (без обращения к базе данных), и сущность не будет добавлена ​​в контекст сохранения JPA. Если он аннотируется только как nullable = false, объект будет добавлен в контекст персистентности, и при попытке записать объект в базу данных (например, через сброс) он попытается записать объект в базу данных, который будет это отрицать, и тогда он вызовет исключение.
Ray Hulha
@RayHulha Я попытался аннотировать поле с помощью «@Basic (optional = false)» и добавил кортеж в базу данных (со значением этого поля = null), никаких исключений не возникло !!, надеюсь, вы сможете объяснить мне такое поведение.
ziMtyth
4

Итак, я попробовал аннотацию @Basic (optional = false) с использованием JPA 2.1 (EclipseLink), и оказалось, что аннотация игнорируется при фактическом использовании (по крайней мере, для поля String). (например, вызовы entityManager.persist).

Итак, я перешел к спецификации и прочитал об этом. Вот что говорится в спецификации:
http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-oth-JSpec/

Базовый (необязательно): может ли значение поля или свойства быть нулевым. Это подсказка, которая игнорируется для примитивных типов; его можно использовать при генерации схемы.

Итак, я думаю, что это предложение объясняет реальный вариант использования Basic (необязательно), который используется при генерации схемы. (То есть: когда вы генерируете CREATE TABLE SQL из классов Java Entity. Это то, что, например, может делать Hibernate.)

Рэй Хулха
источник
1
Забавно, что другой ответ подразумевает, что значение nullable, а не Basic, которое используется для генерации схемы (когда в нем говорится, что «nullable» относится только к столбцам базы данных »). Это все еще очень сбивает с толку. Я предполагаю , что обнуляемый будет использоваться для генерации схемы и Basic (факультативные = False) может быть использована для тех же целей? Имеет ли это смысл?
Маркус
optional = falseпредназначен только для проверки этого ограничения во время выполнения. nullable = falseсоздает ограничение базы данных. Для приложений также optional = falseимеет смысл установить , потому что он оценивается быстрее, чем обращение к базе данных и проверка этого ограничения там ..
nimo23