在 @Column JPA 注释上设置长度属性时有啥作用?

Posted

技术标签:

【中文标题】在 @Column JPA 注释上设置长度属性时有啥作用?【英文标题】:What does the length attribute do when set on the @Column JPA annontation?在 @Column JPA 注释上设置长度属性时有什么作用? 【发布时间】:2011-02-21 22:34:28 【问题描述】:

在 JPA 中设置列​​的长度到底有什么作用?

@Column(name = "middle_name", nullable = false, length = 32)
public String getMiddleName() 
    return this.middleName;

我了解您可以使用注释来基于实体对象生成数据库架构 (DDL),但 length 是否会在持久性发生时进行任何类型的检查或截断,或者它仅用于架构创建?

我还意识到 JPA 可以位于各种实现之上,在这种情况下我关注的实现是 Hibernate。

【问题讨论】:

顺便说一句,如果不设置长度,默认为255(用mysql测试) 【参考方案1】:

当持久性发生时,长度是否会进行任何类型的检查或截断,或者它仅用于创建模式?

Column注解的length属性用于指定:

列长度。 (仅在使用字符串值列时适用。)

And 仅在生成的 DDL 中使用。在您的示例中,结果列将生成为 VARCHAR(32),尝试插入更长的字符串会导致 SQL 错误。


对于验证,您可以从 Bean Validation API (JSR 303) 添加 @Size(max=32) constraint。我提供了一个带有可运行测试的示例here。

同时提供Sizelength 似乎是多余的,但根据Bean Validation 规范的Appendix D.,对于Persistence Providers,生成可识别Bean Validation DDL 并不是强制性的。所以使用length 进行DDL,@Size 进行验证。

如果您有兴趣,只需将 Bean Validation 实现放在 JPA 2.0 的类路径上。对于 JPA 1.0,请参阅此previous answer。

【讨论】:

谢谢,我也很怀疑。您是否碰巧有引用说注释仅适用于 DDL?我无法在文档中找到明确说明。 我尝试同时使用@Size(max=32)@Column(length=128),不幸的是@Size 似乎优先。也许这是一个 Hibernate 错误。 例如,当我创建一个长度为 1500 的列时,它在 MySql 中生成为“TEXT”。在这种情况下如何应用尺寸限制?或者它是否适用?谢谢。 这意味着如果我指定@Column(length=15),则可以插入15个或更少的字符,但不能超过。我说的对吗? 但是,@JavaTechnical,我相信 @Column 注解只有在 DDL 启用时才会生效,即 Hibernate 可以创建/更新/删除您的模式。但是,我想请人在这里确认/拒绝。【参考方案2】:

Hibernate 4.3.11(和其他版本)应该注意验证注解。 - 所以你可能需要升级

这是来自Hibernate 4.3.11 manual的引用

Chapter 22.Additional modules

Hibernate Core 还提供与一些外部的集成 模块/项目。这包括 Hibernate Validator 的参考 Bean Validation (JSR 303) 和 Hibernate Search 的实现。

Chapter 22.1 Bean Validation

... Hibernate 和 Bean Validation 之间的集成在两个方面起作用 水平。首先,它能够检查一个类的内存实例 违反约束。其次,它可以将约束应用于 休眠元模型并将它们合并到生成的数据库中 架构。 ...

Chapter 22.1.4 Database schema

Hibernate 使用 Bean Validation 约束来生成准确的数据库架构:

@NotNull leads to a not null column (unless it conflicts with components or table inheritance)

@Size.max leads to a varchar(max) definition for Strings

@Min, @Max lead to column checks (like value <= max)

@Digits leads to the definition of precision and scale (ever wondered which is which? It's easy now with @Digits :) )

注意:@Lengh 也可以,就像 @Size 一样


当您使用 Hibernate Validator 5.1 时,您还需要一个 el-Implementation。例如

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>el-impl</artifactId>
    <version>2.2</version>
</dependency>

如果你没有这个,那么 Hibernate ORM 将无法启动 Hibernate 验证,因此它不会考虑(全部)JSR-303 例如@Length@Size

【讨论】:

所以,如果我停止 Hibernate 创建模式,并自己使用 SQL 创建表,我不需要指定 @Column(length=...) 等等,对吗?我只检查@Size@Max before 坚持,对吗? @WesternGun:是的,但仍然需要@Column(name="xxx") 谢谢(虽然我认为如果列名与字段名完全相同,name="xxx" 是不必要的,但通常情况并非如此) @WesternGun:是的,抱歉我的评论不清楚:@Column(name="xxx") 当然只有在您需要指定列长度以外的其他设置时才需要【参考方案3】:

@Column(length=32) 仅用于 DDL 目的而不用于限制意味着它允许超过 32 个字符,除非在表级别它不受限制。要限制大小,我们应该去 @Size(max=32)

【讨论】:

以上是关于在 @Column JPA 注释上设置长度属性时有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

Java 持久性/JPA:@Column 与 @Basic

JPA @Column 注释以创建注释/描述

JPA 的基本注解

Hibernate @Column 注释不起作用

请参考 JPA @Column 注释解释 insertable=false 和 updatable=false

JPA:我应该使用哪个?基本(可选)或列(可为空)?