[英]Hibernate Unidirectional OneToMany Relationship with Not-null Constraint in Foreign Key
[英]Why Hibernate ignores not-null constraint?
我遇到过有趣的 Hibernate 行为。 有人可以解释我为什么会发生这种情况吗?
技术栈:Java 11 / Spring boot [2.3.2.RELEASE] / Spring data [2.3.2.RELEASE] / Hibernate [5.4.18.Final]。
我有一个由 liquibase 创建的表:
<changeSet id="create-persons-table" author="author">
<createSequence sequenceName="persons_seq"/>
<createTable tableName="persons">
<column name="id" type="bigint" defaultValueSequenceNext="persons_seq"/>
<column name="name" type="varchar(255)"/>
<column name="lastname" type="varchar(255)"/>
<column name="es_identification" type="varchar(500)">
<constraints nullable="false"/>
</column>
<column name="person_type" type="varchar(255)"/>
</createTable>
</changeSet>
我有三个实体。 基础实体、通用实体和特定国家实体:
@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "seq_gen")
private Long id;
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "person_type")
@SequenceGenerator(name = "seq_gen", sequenceName = "persons_seq", allocationSize = 1)
@Table(name = "persons")
public class Person extends BaseEntity {
private String name;
private String lastname;
}
@Entity
@NoArgsConstructor
@DiscriminatorValue("ES")
@Getter
@Setter
public class EsPerson extends Person {
@Column(name = "es_identification", nullable = false)
private String esIdentification;
}
我有相应的存储库:
@NoRepositoryBean
interface BaseRepository<T extends BaseEntity> extends JpaRepository<T, Long> {
Optional<T> findById(Long id);
default T requireById(Long id) {
checkNotNull(id, "id cannot be null");
return findById(id).orElseThrow(EntityNotFoundException::new);
}
}
public interface PersonRepository extends BaseRepository<Person> {
}
public interface EsPersonRepository extends BaseRepository<EsPerson> {
}
所以当我试图保存 EsPerson 实体时,魔法(对我来说)就开始了。
var person = new EsPerson();
person.setName("name");
person.setLastname("lastname");
person.setEsIdentification("es-identification");
esPersonRepository.save(esPerson);
在调试模式下,我看到所有属性都不为空。 但是当我保存时,我得到了org.postgresql.util.PSQLException: ERROR: null value in column 'es_identification' violates not-null constraint
。
我打开了 sql 日志,我看到休眠插入“名称”、“姓氏”和空值。 之后,我关闭了“es_identification”列上的非空约束,我看到 Hibernate 首先插入“名称”、“姓氏”、空值,然后更新“es_identification”并设置相应的值。
所以这对我来说看起来很奇怪。 为什么 Hibernate 不会在一个操作中插入所有值? 为什么它忽略“非空”约束?
请记住,这是一个足够大的项目,所以也许我在这里错过了一些重要的事情。 只是试图使示例尽可能简单。
为什么Hibernate 会这样做是一个特定于实现的问题。 底线是:单表继承中的子属性不允许非空约束,并且 Hibernate 可以在该假设下自由运行。
原因当然是在插入父实体记录时,子属性对应的列必然为NULL
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.