在外部管理数据库模式时(例如使用Liquibase),除了指定Liquibase变更集之外,还必须使用JPA注释帮助Hibernate理解您的数据结构。
虽然一些注释涉及底层数据(如@Embedded
或@OneToMany
)的更高级别的抽象,但其他较低级别的注释(如@Column(length = 255, nullable = false)
)似乎只表示底层数据库模式(varchar(255) not null
)中已经定义的内容。因此,指定两者都是多余的,它提出了一些我在文档中找不到明确答案的问题:
主要问题是,哪些@Column
设置(除了name
、insertable
和updatable
)仅用于DDL创建,如果数据库模式是外部管理的,那么可以安全地省略吗?
我的猜测是:columnDefinition
、length
、precision
和scale
,但我不确定Hibernate是否在内部使用了这些工具。关于nullable
和unique
,Hibernate是否考虑了这些因素来优化查询,或者这些查询是否也会被忽略?
作为一种测试,我尝试将null写入非空数据库列,而指定
的唯一不同之处是,异常将起源于
EntityManager
,而不是数据库驱动程序,这对应用程序没有多大影响(编辑:假设它是异常情况)。
旁边的问题1是否认为Hibernate在单列主键上具有唯一性和非空性,因此可以在同时具有@Column(unique = true, nullable = false)
的属性上省略@Id
设置。
边问题2,因为Hibernate能够检查数据库模式(例如,在使用hbm2ddl.auto=validate
时),它是否可以配置为从底层模式中提取它需要的类型和约束信息,从而可以省略@Column
中的设置?
发布于 2022-09-29 06:30:41
Hibernate确实使用了一些注释成员,特别是在版本6时。我建议您研究一个像JPABuddy这样的工具,它可以根据实体和清算基础模型之间的差异生成Liquibase变更集。在过去,我在JUnit测试中实现了这样的差异。该测试创建了两个数据库,一个通过hbm2ddl,另一个通过液化基模型。最后,它将两者区分开来,如果有差异,则失败测试,报告XML序列化形式的diff。
这样,两个模型都很容易保持同步,并且您也不需要hbm2ddl验证。
在这里您可以看到运行时模型接收诸如length
、precision
、scale
和columnDefinition
:https://github.com/hibernate/hibernate-orm/blob/6.1.3/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java#L262之类的信息。
在这里,您可以看到正在使用的信息:https://github.com/hibernate/hibernate-orm/blob/6.1.3/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L3629
这种特殊用途是用于转换参数,这些参数可以推断映射属性的类型,例如在像... where alias.attribute = :param
这样的查询中。在某些情况下,某些数据库可能需要使用SQL中的强制转换来包装参数标记。
因此,这只是Hibernate如何使用这些信息的一个小例子。如果您研究Hibernate代码,您可能会发现其他一些用途。
https://stackoverflow.com/questions/73855108
复制