Подтвердить что ты не робот

Смещение 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
4b9b3361

Ответ 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. По умолчанию АВТО.