Java 为什么Hibernate忽略NOTNULL约束?
我遇到了有趣的冬眠行为。谁能解释一下为什么会这样 技术栈:Java11/SpringBoot[2.3.2.RELEASE]/SpringData[2.3.2.RELEASE]/Hibernate[5.4.18.Final] 我有一个由liquibase创建的表:Java 为什么Hibernate忽略NOTNULL约束?,java,spring,hibernate,Java,Spring,Hibernate,我遇到了有趣的冬眠行为。谁能解释一下为什么会这样 技术栈:Java11/SpringBoot[2.3.2.RELEASE]/SpringData[2.3.2.RELEASE]/Hibernate[5.4.18.Final] 我有一个由liquibase创建的表: <changeSet id="create-persons-table" author="author"> <createSequence sequenceName=&q
<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>
我有相应的存储库:
@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);
}
}
在调试模式下,我看到所有属性都不是null。
但是当我保存时,我得到了org.postgresql.util.psqleexception:错误:“es_identification”列中的null值违反了notnull约束
我打开了sql日志,看到hibernate插入了“name”、“lastname”和null。
之后,我关闭了“es_identification”列上的NOTNULL约束,我看到Hibernate首先插入“name”、“lastname”、null,然后更新“es_identification”并设置相应的值
所以这对我来说真的很奇怪。为什么Hibernate不在一个操作中插入所有值?为什么它忽略了“notnull”约束
请记住,这是一个足够大的项目,所以我可能错过了一些重要的东西。只是尽量使示例尽可能简单。为什么Hibernate会这样做是一个特定于实现的问题。底线是:单表继承中的子属性不允许有NOTNULL约束,Hibernate可以在该假设下自由操作
当然,原因是插入父实体记录时,与子属性对应的列必然是
NULL
。为什么Hibernate会这样做是一个特定于实现的问题。底线是:单表继承不允许NOTNULL约束,Hibernate可以在该约束下自由操作assumption@crizzis谢谢你的回答!我不知道单表继承不允许使用非null约束。已经找到了证明你是对的证据!如果你把你的答案从评论中去掉,我可以把它标记为正确的。
@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> {
}
var person = new EsPerson();
person.setName("name");
person.setLastname("lastname");
person.setEsIdentification("es-identification");
esPersonRepository.save(esPerson);