实体对象中空值的最佳实践

3
我正在审核同事的代码。在他的实体对象中,他设置了 nullable = false,并且在 setter 中也检查要设置的值不是 null
这有用吗?无论如何,nullable = false 在某个时刻都会抛出异常。 (如果该值为 null,则 checkArgumentNotNull 将抛出非法参数异常。)
private TypeChampMaterielDefaillant typeChamp;

@Column(name = "TYPE_CHAMP", nullable = false, length = 30)
@Enumerated(EnumType.STRING)
public TypeChampMaterielDefaillant getTypeChamp() {
    return typeChamp;
}

public void setTypeChamp(TypeChampMaterielDefaillant typeChamp) {
    checkArgumentNotNull(typeChamp, "typeChamp");
    this.typeChamp = typeChamp;
}

编辑

如果我理解正确,nullable=false仅适用于模式生成,因此如果当前实体没有生成数据库,则可以将null值持久化。

3个回答

3

参数 nullable = false 会在数据库操作中出现(您将无法将此值等于 null 的实体持久化)。在 setter 中进行额外的检查很有用,因为您可以更早地获得异常(在 setter 调用期间),但不是必需的。


@PeterRader 是的,但它会发生在持久化期间而不是调用setter时。 - Jakub Kubrynski
实际上,我从未见过在将nullable = false注释并保存为null时抛出异常,我认为当您使用Hibernate生成ddl模式时,这将非常有用,Hibernate可能会为其创建约束。 - Elbek
@Elbek 你说得没错,但如果你使用Hibernate来生成模式,它将保证不会有空值。使用setter的想法是在设置值时获得异常,而不是在持久化期间。 - Jakub Kubrynski
更正一下,Hibernate并不保证这一点,而是由数据库服务器来实现。Hibernate只是生成正确的DDL,仅此而已。 - Elbek

0
不,这是非常糟糕的做法。Hibernate-Bean是一个bean,任何智能setter都是一种变通方法。
相反,应该使用注释,例如@NotNull!
如果你真的需要在测试/开发中抛出异常,可以使用断言!

任何评论或者“仅仅因为”? - Jakub Kubrynski
1
断言不应该只用于调试/测试目的吗? - holap
@holap 是的,你说得对(我会说“debug/test/devel”)。所以最好使用注释。我只是写了这个因为如果有空值,setter应该失效。如果你需要抛出异常,那么使用AsserationError,但永远不要让它成为实际系统的一部分。 - Grim

0
我认为 nullable = false 用于模式生成,而不是用于 JPA 验证(除非某些第三方库在持久化之前使用它进行验证)。 JPA 2.1 规范
11.2.2.1 Column 
The following elements of the Column annotation are used in schema generation: 
name 
unique 
nullable 
columnDefinition 
table 
length (string-valued columns only) 
precision (exact numeric (decimal/numeric) columns only) 
scale (exact numeric (decimal/numeric) columns only) 
See section 11.1.9 for the rules that apply to these elements and column creation. The AttributeOverride annotation may be used to override column
mappings.

正如您所看到的,JPA规范并没有涉及验证,除非Hibernate或某些第三方库进行了扩展。我对于Hibernate验证器是否支持nullable = false语句也不确定。

最好使用一些验证框架或使用@PrePersist、@PreUpdate注解。

Setter验证也不太好,如果用户根本没有调用它怎么办?


哦,https://dev59.com/1Gs05IYBdhLWcg3wG-RR 说,这不是用于验证。是我的错误。 - Grim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接