Hibernate Tips: How to perform different validations for persist and update
Take your skills to the next level!
The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, monthly Java Persistence News, monthly coding problems, and regular expert sessions.
Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. If you have a question for a future Hibernate Tip, please post a comment below.
Question:
I’m using BeanValidation to validate my entities automatically before they get persisted and updated. I defined different ValidationGroups for INSERT and UPDATE operations.
Can I tell Hibernate which ValidationGroups it shall use before persisting or updating an entity?
Solution:
Yes, the JPA specification defines a set of configuration parameters to configure which ValidationGroups shall be validated before performing an insert, update, and remove operations.
Let’s take a look at an example.
Defining the Validation
The JPA and BeanValidation specifications integrate very easily. You can annotate your entity attributes with BeanValidation annotations, which specify the validation you want to perform. The validation will then get triggered automatically before each lifecycle state change.
In the following code snippet, I use the @Min and the @Max annotations to ensure that the numPages attribute contains a value between 100 and 1000.
@Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; @Min(value = 100, groups = PublishedBook.class) @Max(1000) private int numPages; ... }
The @Min validation references the PublishedBook interface as a ValidationGroup. This validation is now part of the PublishedBook ValidationGroup and no longer part of the default group.
public interface PublishedBook {}
Configuring Different ValidationGroups for Persist and Update
In the next step, you can set which ValidationGroups shall be validated before an entity gets persisted, updated, or removed. By default, your JPA implementation uses the default group before persisting and updating an entity and doesn’t perform any validation before removing it.
You can change that in your persistence.xml file using the following parameters:
- javax.persistence.validation.group.pre-persist
- javax.persistence.validation.group.pre-update
- javax.persistence.validation.group.pre-remove
In this example, I use the javax.persistence.validation.group.pre-update to tell Hibernate to validate the org.thoughts.on.java.validation.PublishedBook ValidationGroup before an entity gets updated.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="my-persistence-unit"> <description>Hibernate Tips</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/recipes" /> <property name="javax.persistence.jdbc.user" value="postgres" /> <property name="javax.persistence.jdbc.password" value="postgres" /> <property name="javax.persistence.validation.group.pre-update" value="org.thoughts.on.java.validation.PublishedBook" /> </properties> </persistence-unit> </persistence>
I don’t change the default groups for the pre-persist and pre-remove validation. So, before an entity gets persisted, Hibernate will trigger the validation of the default group and will not trigger any validation before the entity gets removed.
Learn more:
To learn more about BeanValidation and its integration with JPA, please take a look at the following articles:
- How to automatically validate entities with Hibernate Validator
- Hibernate Tips: Validate that only 1 of 2 associations is not null
- Hibernate Tips: How to validate that an entity attribute value is within a defined range
- Hibernate Tips: What’s the difference between @Column(nullable = false) and @NotNull
Hibernate Tips Book
Get more recipes like this one in my new book Hibernate Tips: More than 70 solutions to common Hibernate problems.
It gives you more than 70 ready-to-use recipes for topics like basic and advanced mappings, logging, Java 8 support, caching, and statically and dynamically defined queries.