可空性
实体对象属性是否允许为null这个问题,Jimmer用非常严格的方式处理。即便对Java开发者而言,也要求如同kotlin开发者一样认真考虑思考每个属性是否允许为null。
明确说明实体对象的每个属性是否允许为null,对Jimmer而言非常重要,很多功能都会受其影响。
定义属性的可空性
Kotlin
Kotlin支持空安全,T 表示非空,T? 表示可为空,按照kotlin的本身的方式声明实体属性即可。
Java
Java下属性是否为null,靠以下规则制定
-
如果属性类型为boolean、char、byte、short、int、long、float或double,则非null
-
如果属性类型为Boolean、Character、Byte、Short、Integer、Long、Float或Double,则可null
-
否则
-
如果属性被任何简名为
Nullable或Null的annotation修饰,则可null -
否则,默认非null
备注推荐使用
org.jetbrains.annotations.Nullable,因为-
虽然可识别的annotation不受限制,但是如果使用了未被Jimmer annotation processor默认包含的annotation,需要将其依赖添加到annotation processor中,这终归是麻烦。
-
org.jetbrains.annotations.Nullable受Intellij支持
-
注意事项
这里会出现一系列现在没讲解的概念,它们都会在后续文档中讲解。
这里仅仅做一个注意事项的简单罗列,请读者先忽略这些名词,本文也不提供相关例子,读者了解所有后续概念后再回来查看。
-
@Id属性必须非null和JPA/Hibernate有很大不同
-
JPA/Hibernate推荐将id属性声明为可空类型,比如,对Java而言,就是
Long而非long,这样,保存数据时可表达没有id而需要自动分配的情况。 -
Jimmer必须将id属性声明为非空类型,比如,对Java而言,就是
long而非Long。Jimmer靠实体对象本身的动态性来表达id属性的缺失。
-
-
一对多和多对多属性必须非null
一对多和多对多属性用长度为0的集合表示没数据,而非null。
-
当以下任何一种情况满足时,一对一和多对一属性必须可null
-
基于中间表映射,而非外键
-
基于伪外键,而非真实外键
信息所谓“伪外键”,指在开发人员意识中是外键,但是数据库中并没有对应的外键约束。
-
远程关联
-
作为镜像端的@OneToOne关联
-
-
如果关联实体被施加了全局过滤器,那么,对于一对多/多对一关联而言,即使直接基于外键也必须可null,除非以下条件全部满足:
-
所有被施加于关联实体的全局过滤器都实现了
AssociationIntegrityAssuranceFilter/KAssociationIntegrityAssuranceFilter接口。 -
所有被施加于关联实体的全局过滤器也被施加于当前实体。
-
inputNotNull
如果前文所言,由于某些特有的查询场景,基于外键的一对一和多对一属性必须被声明为可空的。
然而,在保存数据时,开发人员可能不期望用户将数据库的外键字段修改为null。这时,可以将@OneToOne或@ManyToOne的inputNotNull设置为true,例如
-
@OneToOne(inputNotNull = true) -
@ManyToOne(inputNotNull = true)
如果某个关联属性配置了inputNotNull,在数据库验证中会被优先考虑,从而验证数据库中外键字段不能为null。