I tried to migrate my application from Hibernate 5.4.30.Final to 6.1.6.Final, database H2 2.1.214. I observed a different behaviour regarding generics when using a CriteriaQuery. I have stripped it down to a testcase (which does not make any sense but shows the problem). In Hibernate 5 the following query to a generic field name runs fine whereas Hibernate 6 throws an Exception.
CriteriaBuilder cb = eMgr.getCriteriaBuilder();
CriteriaQuery<String> cr = cb.createQuery(String.class);
Root<Person> person = cr.from(Person.class);
cr.select(person.<String> get("name"));
TypedQuery<String> query = eMgr.createQuery(cr);
Exception:
Converting `org.hibernate.query.QueryTypeMismatchException` to JPA `PersistenceException` : Specified result type [java.lang.String] did not match Query selection type [java.lang.Object] - multiple selections: use Tuple or array
Here are my sample class definitions:
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class GenericPerson<T>
{
@Id
@GeneratedValue(generator = "increment")
private long id;
private T name;
public GenericPerson() { }
public GenericPerson(T name) { this.name = name;}
public T getName() { return this.name; }
public void setName(T name) { this.name = name; }
public long getId() { return this.id;}
public void setId(long id) { this.id = id; }
}
@Entity
public class Person extends GenericPerson<String>
{
public Person() { }
public Person(String name) { super(name); }
}
Hibernate 5 seems to handle generics differently to Hibernate 6 but I could not find any hint in the migration document. Why fails the test case with Hibernate 6?
The solution is to use the cast method for the generic field:
cr.select(person.get("name").as(String.class));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With