注释@Basic到底做了什么?

2022-09-04 02:26:31

似乎对 java 变量的注释仅声明该变量必须另存为具有 NOT NULL 约束的列。这是对的吗?@Basic

这篇文章说:

@Basic(optional = false) @Column(nullable = false) @Basic 注释在 Java 对象级别上将属性标记为非可选。第二个设置(列映射上的 nullable = false)仅负责生成 NOT NULL 数据库约束。在任何情况下,Hibernate JPA 实现都以相同的方式处理这两个选项,因此您不妨只使用其中一个注释来实现此目的。

我很困惑。这是什么意思 - 在Java级别,属性或变量如何“可选”?The @Basic annotation marks the property as not optional on the Java object level.


答案 1

Hibernate JPA 实现仅在模式生成方面将两者视为相同,即列将使用非空约束创建。

但是,如果非可选字段为 null,则使用 optional = false 也允许 Hibernate(以及我想其他实现)在刷新到数据库之前执行检查并引发异常。没有这个,你只会在尝试插入后引发一个异常。

来自 Pro JPA:

当可选元素指定为 false 时,它会向提供程序指示字段或属性映射可能不是 null。当值为 null 时,API 实际上并未定义行为是什么,但提供程序可能会选择引发异常或仅执行其他操作。对于基本映射,它只是一个提示,可以完全忽略。在执行架构生成时,提供程序也可以使用可选元素,因为如果 optional 设置为 true,则数据库中的列也必须为 null。

具有 optional=false 也会影响休眠中的实体加载。例如,单端关联始终在休眠中预先加载,除非该关联被标记为 optional=false。

请参阅:https://stackoverflow.com/a/17987718/1356423 以获取进一步说明。


答案 2

对 api 元素含义的权威答案当然是 api 文档,即 javadoc。对于@Basic注释,它写道

映射到数据库列的最简单类型。Basic 注释可以应用于以下任何类型的持久属性或实例变量:Java 基元类型、基元类型的包装器、String、java.math.BigInteger、java.math.BigDecimal、java.util.Date、java.util.Calendar、java.sql.Date、java.sql.Time、java.sql.Timestamp、byte[]、Byte[]、Byte[]、char[]、Character[]、枚举以及实现 java.io.Serializable 的任何其他类型。

对于这些类型的持久性字段和属性,基本批注的使用是可选的。如果未为此类字段或属性指定“基本”批注,则将应用“基本”批注的默认值。

基本注释的值是什么?Javadoc也解释了它们:

public abstract FetchType fetch

(可选)定义是应延迟加载字段或属性的值,还是必须紧急获取。EAGER 策略是持久性提供程序运行时的一项要求,即必须热切地获取值。LAZY 策略是对持久性提供程序运行时的提示。如果未指定,则默认为 EAGER。

public abstract boolean optional

(可选)定义字段或属性的值是否可以为 null。这是一个提示,对于基元类型是忽略的;它可以用于架构生成。如果未指定,则默认为 true。

因此,如果设置为 ,则当您尝试持久化或更新属性为 null 的对象时,持久性提供程序可能会引发异常。如果您的业务规则说 null 不是合法值,这可能很有用。optionalfalse

注意

至少在使用休眠时,可以使用相应的 Bean 验证注释(@NotNull)更好地表示可空性,因为此注释既可以通过休眠来理解,也可以由应用程序上的其他层使用(例如,在验证用户输入时)。


推荐