Смещение Hibernate с помощью nullable = true в @Column
Я использую Hibernate с Springs, поддерживаемый db Mysql.
Вот сущность, подобная той, которую я использую для записи
@Entity
@Table(name = "my_table") {
@Basic
@Column(name = "my_string", nullable = false)
private String myString;
}
Определение sql
CREATE TABLE `my_table` (
`my_string` varchar(200) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Несмотря на то, что таблица допускает нулевые значения, столбец myString не имеет значения NULL в соответствии с аннотацией JPA. Это приводит к непредсказуемому поведению.
Q: Является ли недействительный ALWAYS принудительным на уровне сущности при создании вставок? Или есть какой-то случай, в котором его можно игнорировать
Я ожидал, что все записи должны быть отклонены. Но с этой настройкой многие записи ( > 7000) вошли в таблицу.
Только иногда я получаю исключение DataIntegrityViolation из spring
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: ...; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: ....
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:652)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
....
....
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:103)
....
Я понимаю, что наличие отдельной подписи в сущности и таблице является плохой практикой. Но я пытаюсь определить, что вызывает это поведение и любые другие лазейки, которые могли быть оставлены из-за этого.
Versions -
Mysql- 5.5
Hibernate - 4.0.0
Hibernate-jpa - 2.0
Spring-core- 3.1.0
Spring-jdbc- 3.1.2
Ответы
Ответ 1
Люди часто путают аннотации @Column (nullable) и @NotNull.
@Column(nullable)
предназначен для сгенерированных сценариев DDL. Но вы не используете Hibernate для генерации DDL, поэтому вам не следует полагаться на него вообще. Вы хотите @NotNull
, который является триггером проверки выполнения.
Если вы определяете аннотацию валидатора Hibernate (или JPA 2.0) вы также можете получить DDL для них:
Из коробки, Hibernate (начиная с версии 3.5.x) будет переводить ограничения, которые вы определили для своих объектов в метаданных сопоставления. Например, если свойство вашего объекта аннотируется @NotNull, его столбцы будут объявлены как не равные нулю в схеме DDL, сгенерированной Спящий режим.
И убедитесь, что вы включили проверку, если используете JPA с Hibernate.
Если вы используете JPA 2 и Hibernate Validator находится в пути к классам Для спецификации JPA2 требуется, чтобы Bean Validation активировалась. свойства javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update и javax.persistence.validation.group.pre-remove, как описано в разделе 10.1.2, "проверка на основе событий на гибернате" в этом случае может быть сконфигурирована в файле persistence.xml. persistence.xml также определяет nodeрежим проверки, который может быть установлен на AUTO, CALLBACK, NONE. По умолчанию АВТО.