Why does Hibernate Tools hbm2ddl generation not take into account Bean Validation annotations?

StackOverflow https://stackoverflow.com/questions/17398760

  •  02-06-2022
  •  | 
  •  

Question

Summary: I'm using Hibernate Tools 4.0.0-CR1 and Hibernate 4.2 (including Hibernate Validator), but Bean Validations are not picked up. The schema is properly generated when deploying with hibernate.hbm2ddl.auto=create-drop.

But I prefer to generate my DDL via the following build.xml target:

<target name="schemaexport" depends="jar" description="Exports a generated schema to DB and files">
    <path id="lib.path">
        <fileset refid="lib" />
        <pathelement location="${jboss.home}/modules/org/apache/xerces/main/xercesImpl-2.9.1-jbossas-1.jar"/>
        <pathelement location="${jar.dir}" />
    </path>

    <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask"
             classpathref="lib.path"/>

    <hibernatetool destdir="${basedir}">
        <classpath refid="lib.path"/>
        <jpaconfiguration persistenceunit="TIC" propertyfile="hibernate-console.properties" />
        <hbm2ddl outputfilename="${dist.dir}/db_ddl.sql" format="true"/>
    </hibernatetool>

    <concat destfile="${dist.dir}/tic.sql" fixlastline="yes">
        <filelist dir="${dist.dir}" files="db_ddl.sql" />
        <filelist dir="${jar.dir}" files="import.sql" />
    </concat>
</target>

My hibernate-console.properties is as follows:

hibernate.connection.password=tic
hibernate.connection.username=tic
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.url=jdbc:postgresql://127.0.0.1:5432/db

hibernate.connection.provider_class=org.hibernate.connection.DriverManagerConnectionProvider
hibernate.datasource=
hibernate.transaction.manager_lookup_class=

I double-checked that the jars are in my lib.path...

A sample entity looks like this:

@Entity
public class Title implements Serializable {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Size(max = 50) @NotEmpty @Column(length = 50)
    private String titlename;

    @Size(max = 50)
    private String shortTitle;
}

The problem here is that hbm2ddl generates a proper "varchar(50)" for "titlename" but a generic "varchar(255)" for "shortTitle". I encountered similar problems with @NotNull and basically every other bean validation annotation. According to the manual this should just work[tm]. What am I doing wrong?

Was it helpful?

Solution

You need to distinguish validation api and java persistence api (jpa) (and vendor specific persistence api). Hibernate take into account JPA configuration (and hibernate persistence api) and when you do not provide such configuration then Convention Over Configuration principle is involved to this process. It is why you get varchar(255) for

@Size(max = 50)
private String shortTitle;

it equals to (i omitted other default values)

@Size(max = 50)
@Column(length = 255, nullable = true)
private String shortTitle;

Validation api is involved for validation purposes. To check if the fields properly filled. There can be exist the different validation rules for the same field.


Updated

I mean this http://beanvalidation.org/1.0/spec/#constraintsdefinitionimplementation-constraintdefinition-groups.

For one group you validate one constraint, for other group you validate other constraint.

For example

@NotNull(groups = DefaultGroup.class)
@Null(groups = SecondGroup.class)
private String shortTitle;

and then

    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    Set<ConstraintViolation<Title>> constraintViolations = validator.validate(title, DefaultGroup.class);
    Set<ConstraintViolation<Title>> secondConstraintViolations = validator.validate(title, SecondGroup.class);

OTHER TIPS

Try removing @Size(max=50), use @Column(length = 50) only. Also add @Column(length = 50) to variable shortTitle.

@NotEmpty @Column(length = 50)
private String titlename;

/** User visible short version of the title. */
@Column(length = 50)
private String shortTitle;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top