Search results
Generate JPA Metamodel Classes with Hibernate Maven Plugin
pom.xml
<dependencies>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<!-- Path to Lombok processor -->
<!-- ... -->
<!-- Path to Mapstruct processor -->
<!-- ... -->
<!-- Path to Hibernate JPA Metamodel processor -->
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
annotationProcessorPaths order matters, place hibernate-jpamodelgen processor after Lombok’s.
Usage
mvn clean package
...
[INFO] Hibernate compile-time tooling 6.6.36.Final
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...
ls target/generated-sources/annotations/com/asimiotech/demo/domain/
ActorInfoId_.java Country_.java FilmCategoryId_.java Language_.java SalesByFilmCategory_.java Store_.java
ActorInfo_.java CustomerListId_.java FilmCategory_.java NicerButSlowerFilmListId_.java SalesByStoreId_.java
Actor_.java CustomerList_.java FilmListId_.java NicerButSlowerFilmList_.java SalesByStore_.java
Address_.java Customer_.java FilmList_.java Payment_.java StaffListId_.java
Category_.java FilmActorId_.java Film_.java Rental_.java StaffList_.java
City_.java FilmActor_.java Inventory_.java SalesByFilmCategoryId_.java Staff_.java
Generated JPA Metamodel class example:
cat target/generated-sources/annotations/com/asimiotech/demo/domain/Film_.java
...
@StaticMetamodel(Film.class)
@Generated("org.hibernate.processor.HibernateProcessor")
public abstract class Film_ {
public static final String RENTAL_RATE = "rentalRate";
public static final String RENTAL_DURATION = "rentalDuration";
public static final String FILM_CATEGORIES = "filmCategories";
public static final String LENGTH = "length";
public static final String RATING = "rating";
public static final String DESCRIPTION = "description";
public static final String REPLACEMENT_COST = "replacementCost";
public static final String LANGUAGE = "language";
public static final String TITLE = "title";
public static final String FILM_ACTORS = "filmActors";
public static final String SPECIAL_FEATURES = "specialFeatures";
public static final String INVENTORIES = "inventories";
public static final String FILM_ID = "filmId";
public static final String LAST_UPDATE = "lastUpdate";
public static final String FULLTEXT = "fulltext";
public static final String RELEASE_YEAR = "releaseYear";
/**
* @see com.asimiotech.demo.domain.Film#rentalRate
**/
public static volatile SingularAttribute<Film, BigDecimal> rentalRate;
/**
* @see com.asimiotech.demo.domain.Film#rentalDuration
**/
public static volatile SingularAttribute<Film, Short> rentalDuration;
/**
* @see com.asimiotech.demo.domain.Film#filmCategories
**/
public static volatile SetAttribute<Film, FilmCategory> filmCategories;
/**
* @see com.asimiotech.demo.domain.Film#length
**/
public static volatile SingularAttribute<Film, Short> length;
/**
* @see com.asimiotech.demo.domain.Film#rating
**/
public static volatile SingularAttribute<Film, String> rating;
/**
* @see com.asimiotech.demo.domain.Film#description
**/
public static volatile SingularAttribute<Film, String> description;
// ...
Writing JPA/Hibernate type-safe queries with Criteria API and Metamodel generated classes:
FilmSpecifications.java
public final class FilmSpecifications {
private FilmSpecifications() {
}
public static Specification<Film> createFilmSpecifications(FilmSearchCriteria searchCriteria) {
return rentalRateBetween(searchCriteria.getMinRentalRate(), searchCriteria.getMaxRentalRate())
.and(releaseYearEqualTo(searchCriteria.getReleaseYear()))
.and(categoryIn(searchCriteria.getCategories()));
}
public static Specification<Film> rentalRateBetween(Optional<BigDecimal> minRate, Optional<BigDecimal> maxRate) {
return (root, query, builder) -> {
return minRate.map(min -> {
return maxRate.map(max -> builder.between(root.get(Film_.rentalRate), min, max)
).orElse(null);
}).orElse(null);
};
}
public static Specification<Film> releaseYearEqualTo(Optional<Long> releaseYear) {
return (root, query, builder) -> {
return releaseYear.map(relYear -> builder.equal(root.get(Film_.releaseYear), String.valueOf(relYear))
).orElse(null);
};
}
public static Specification<Film> categoryIn(Set<String> categories) {
if (CollectionUtils.isEmpty(categories)) {
return null;
}
return (root, query, builder) -> {
Join<Film, FilmCategory> filmCategoryJoin = root.join(Film_.filmCategories);
Join<FilmCategory, Category> categoryJoin = filmCategoryJoin.join(FilmCategory_.category);
return categoryJoin.get(Category_.name).in(categories);
};
}
}
No need to copy the Metamodel classes to the project.
