We just finished migrating a large project from Hibernate Criteria to JPA Criteria.
With a simple wrapper around the API and a lot of delegate methods and helpers, the migration is straight forward and LOC stayed nearly the same. E.g:
The code is typesafe and easier to read and understand in many cases.
We ran into four main issues:
-
sqlRestriction
As mentioned above, support is missing but we were able to replace all usages with built-in or customfunction
calls -
Custom
Types
We are unable to query custom types such asorg.joda.money.Money
directly. Hibernate criteria allowed us to write something likeRestrictions.eq("price", new Money(EUR, 10)
. This fails with a NPE when using JPA criteria, but might be an issue in the Jadira UserType library. We have to investigate further. -
@AnyType
This was the most annoying problem. We are using Hibernate’s@AnyType
in a couple of entities. JPA Criteria does not support this type at all. It is not included in the metamodel and cannot be used in queries. Since@AnyType
is not deprecated, I would expect support for it in HQL and criteria queries.
For now, we worked around it by adding two virtual columns for each such type. E.g.
@Any(metaDef = "likeable", metaColumn = @Column(name = "target_type"), optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "target_id", nullable = false, updatable = false)
private Likeable target;
@Column(name = "target_id", insertable = false, updatable = false, nullable = false)
private Long targetId;
@Column(name = "target_type", insertable = false, updatable = false, nullable = false)
private String targetType;
-
AttributeConverter
This is an issue with the metamodel rather than JPA criteria. Types that convert from basic values to collections using@Convert
are not recognized by the metamodel. There is an open ticket for this: https://hibernate.atlassian.net/browse/HHH-11803.
@Convert(converter = StringToListConverter.class)
private List<String> groups;
org.hibernate.metamodel.internal.MetadataContext - HHH015007: Illegal argument on static metamodel field injection : Community_#groups; expected type : org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl; encountered type : javax.persistence.metamodel.ListAttribute
Are there any plans to support @Convert
and @AnyType
in JPA criteria?
Thomas