72

What exactly does setting the length on a column do in JPA?

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

I understand that you can use the annotations to generate the database schema (DDL) based on the entity objects, but does length do any sort of check or truncation when persistence happens, or it solely used for schema creation?

I also realize that JPA can sit on top of various implementations, the implementation I am concerned with in this case is Hibernate.

James McMahon
  • 48,506
  • 64
  • 207
  • 283

3 Answers3

99

Does length do any sort of check or truncation when persistence happens, or it solely used for schema creation?

The length attribute of the Column annotation is used to specify:

The column length. (Applies only if a string-valued column is used.)

And is only used in the generated DDL. In your example, the resulting column would be generated as a VARCHAR(32) and trying to insert a longer string would result in an SQL error.


For validation, you could add a @Size(max=32) constraint from the Bean Validation API (JSR 303). I provided a sample with a runnable test here.

Providing both Size and length may seem redundant but according to the Appendix D. of the Bean Validation spec, generating Bean Validation-aware DDL is not mandatory for Persistence Providers. So use length for the DDL, @Size for validation.

In case you're interested, just put a Bean Validation implementation on the classpath with JPA 2.0. With JPA 1.0, refer to this previous answer.

Community
  • 1
  • 1
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • 2
    Thank you, I suspected as much. Do you happen to have a citation that says the annotation is only for the DDL? I wasn't able to find it explicitly stated in the documentation. – James McMahon May 20 '10 at 18:08
  • 1
    I tried to use both `@Size(max=32)` and `@Column(length=128)` and unfortunately `@Size` seems to take precedence. Perhaps this is a Hibernate bug. – James Ward Oct 31 '11 at 15:43
  • 1
    For instance when i create a column with length 1500, it is generated as a "TEXT" in MySql. How is the size restriction apply in this case? Or does it apply at all? Thanks. – rpr Sep 17 '12 at 12:15
  • That means if I specify `@Column(length=15)`, either 15 or less characters can be inserted but not more than that. Am I right? – JavaTechnical Jun 28 '14 at 10:59
  • 1
    but, @JavaTechnical, I believe that that `@Column` Annotation would only take effect if `DDL`, i.e. Hibernate can create/update/delete your Schema, was enabled. But, I'd ask for someone to please confirm/deny here. – Kevin Meredith Sep 02 '14 at 18:45
  • I find this page of documentation of another implementation of JPA, EclipseLink, which implies the same. It reads: `The column size and type info can be set through the @Column annotation.` and the webpage is about DDL generation. Check this page: http://wiki.eclipse.org/EclipseLink/Examples/JPA/DDL – WesternGun Jan 31 '19 at 15:42
6

Hibernate 4.3.11 (and other Versions) should pay attention to Validation Annotations. - so you maybe have to upgrade

This are cites from Hibernate 4.3.11 manual

Chapter 22.Additional modules

Hibernate Core also offers integration with some external modules/projects. This includes Hibernate Validator the reference implementation of Bean Validation (JSR 303) and Hibernate Search.

Chapter 22.1 Bean Validation

... The integration between Hibernate and Bean Validation works at two levels. First, it is able to check in-memory instances of a class for constraint violations. Second, it can apply the constraints to the Hibernate metamodel and incorporate them into the generated database schema. ...

Chapter 22.1.4 Database schema

Hibernate uses Bean Validation constraints to generate an accurate database schema:

@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 :) )

Note: @Lengh works too, like @Size


When you use Hibernate Validator 5.1 - then you also need an el-Implementation. For example

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

If you do not have this, then Hibernate ORM will not been able to start Hibernate Validation, ad therefore it would not take (all) JSR-303 for example @Length, @Size in account!

Ralph
  • 118,862
  • 56
  • 287
  • 383
  • 1
    So, if I stop Hibernate from creating the schema, and create the table with SQL myself, I don't need to specify `@Column(length=...)` and so on, right? I only check the `@Size`, `@Max` _before_ persisting, is that correct? – WesternGun Jan 31 '19 at 15:46
  • 1
    @WesternGun: yes, but `@Column(name="xxx")` is still needed – Ralph Feb 02 '19 at 08:35
  • Thanks(although I would argue that `name="xxx"` would be unnecessary if the column name is exactly the same as the field name, but it is usually not the case) – WesternGun Feb 04 '19 at 12:05
  • @WesternGun: yes, sorry that i was not clear with my comment: `@Column(name="xxx")` is of course only needed if you need to specify some other settings than the column lenght – Ralph Feb 05 '19 at 08:24
5

@Column(length=32) is only for DDL purpose and not for restricting means it allows more than 32 characters unless at table level it is not restricted.To restrict size we should go for @Size(max=32)

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
lingaraju p
  • 51
  • 1
  • 1