The following criteria query where the Parameter’s type is Object and the value is an Embedded throws an AssertionError. If the parameter is correctly typed it works. For the Object type Parameter, querying for a simple value like a string also works.
{code:java}final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery<WithEmbedded> query = cb.createQuery(WithEmbedded.class); final Root<WithEmbedded> root = query.from(WithEmbedded.class);
//deliberately using Object type here, using AnEmbeddable works final ParameterExpression<Object> parameter = cb.parameter(Object.class); query.select(root).where(cb.equal(root.get("e"), parameter));
final TypedQuery<WithEmbedded> typedQuery = entityManager.createQuery(query); typedQuery.setParameter(parameter, new AnEmbeddable("a", "b")); typedQuery.getResultList(); //throws AssertionError{code}
{code:none}java.lang.AssertionError at org.hibernate.query.sqm.internal.SqmUtil.createValueBindings(SqmUtil.java:401) at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:326) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:393) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:300) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:276) at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:571) at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:363) at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1073) at org.hibernate.query.Query.getResultList(Query.java:94){code}
While this might seem contrived on its own, it happens with the following spring data jpa code:
{noformat}@Embeddable data class AnEmbeddable(@Column(nullable = false) val foo: String, @Column(nullable = false) val bar: String)
interface HasEmbeddable{ val e: AnEmbeddable }
@Entity class WithEmbedded(@Id val id: Long, @Embedded override val e: AnEmbeddable): HasEmbeddable
@NoRepositoryBean interface HasEmbeddableRepository<T: HasEmbeddable, ID, in AnEmbeddable> : JpaRepository<T, ID>{ fun findByE(e: AnEmbeddable): List<WithEmbedded> }
interface WithEmbeddedRepository: HasEmbeddableRepository<WithEmbedded, Long, AnEmbeddable>{noformat}
Please find a hibernate test here: [https://github.com/noffke/criteria-embedded-parameter-test|https://github.com/noffke/criteria-embedded-parameter-test|smart-link]
Corresponding test case for spring data: [https://github.com/noffke/spring-data-jpa-embedded-test/blob/master/src/test/kotlin/com/example/embeddedtest/springdatajpa/SpringDataJpaTest.kt|https://github.com/noffke/spring-data-jpa-embedded-test/blob/master/src/test/kotlin/com/example/embeddedtest/springdatajpa/SpringDataJpaTest.kt|smart-link] |
|