I have code like this in JPQL and Spring Data JPA
@Query("SELECT bt FROM Textmessage t " +
"JOIN bt.hashtags h " +
"JOIN h.tag t " +
"JOIN t.type tt " +
"WHERE t= :mainTag " +
"GROUP BY bt " +
"ORDER BY " +
" SUM(CASE WHEN t IN :questionTags THEN tt.weight ELSE 0 END) DESC")
List<BotreaderTextmessage> findAnswers(
@Param("mainTag") Tag mainTag,
@Param("questionTags") List<Tag> questionTags
);
but when i run the query this exception has happend
class org.hibernate.type.internal.NamedBasicTypeImpl cannot be cast to class org.hibernate.metamodel.mapping.EntityValuedModelPart (org.hibernate.type.internal.NamedBasicTypeImpl and org.hibernate.metamodel.mapping.EntityValuedModelPart are in unnamed module of loader 'app')
I tested the code without the 'order by' condition and without 'case,' and it works well. However, when I add this code, the above error is displayed to me.
I even wrote the query as follows, which might result in different output and query, but it still gave me the above error.
@Query("SELECT bt, " +
"CASE WHEN bttag IN :tags THEN (SELECT SUM(bttagtype.weight) FROM Textmessage btq " +
"JOIN btq.Hashtags bthq " +
"JOIN bthq.tag bttagq " +
"JOIN bttagq.type bttagtype " +
"WHERE btq.id = bt.id) ELSE 0 END AS tagWeight " +
"FROM Textmessage bt " +
"LEFT JOIN bt.hashtags bth " +
"LEFT JOIN bth.tag bttag " +
"ORDER BY tagWeight DESC")
List<Object[]> findAnswerMessagesByChatIdOrderedByTagWeight(
@Param("tags") List<BotreaderTag> tags);
In my case there were two different things that caused this relating to the IN
predicate. This issue is specific to Hibernate and not Spring.
The parameter you are passing for IN :questionTags
was, in my case, just an Object when it needs to be a Collection instead.
Your example didn't involve CriteriaBuilder, but after Hibernate 6.x, a Root no longer serves as a stand-in for its own ID, and the same Exception is thrown.
Previously you could do an "in" predicate providing only the root, like this, where "ids" is an integer list:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Thing> q = cb.createQuery(Thing.class);
Root<Thing> thing = q.from(Thing.class);
predicates.add(thing.in(ids));
But after 6.x, you need to specify the metamodel's ID field.
predicates.add(thing.get(Thing_.id).in(ids));