[Fixed] Validation failed for query, cannot compare left expression of type with right expression of type – Java

by
Alexei Petrov
hibernate java spring-boot spring-data-jpa

Quick Fix: In the latest version of Hibernate (8.x), to avoid semantic exception due to data type mismatch in join statements, explicitly specify fields when joining tables. For example, instead of ur.user = u.id, use ur.user.id = u.id where UserRole.user is mapped to User.id. This ensures data type consistency and resolves the error.

The Problem:

A situation has been encountered where an upgrade from Spring Boot 3.1.5 to 3.2.0 resulted in an issue within queries involving entity relationships. The error message received is: ‘Cannot compare left expression of type ‘com.acme.domain.AbstractEntity’ with right expression of type ‘com.acme.domain.User”.

An analysis of the code reveals that ‘User’ extends ‘AbstractEntity’ and implements the ‘Identifiable’ interface with a ‘T getId()’ method. However, when executing a query that joins ‘User’ and ‘AuditEventUser’ entities, Hibernate appears to disregard the ‘Identifiable’ bound and fails to locate an id on ‘AbstractEntity’.

The goal is to resolve this error and enable the queries to function correctly again without resorting to workarounds.

The Solutions:

Solution 1: Using explicit join condition

The error message suggests that Hibernate is unable to compare expressions of different types. This can happen when the join condition in a query references fields of different types. In this case, the join condition `a.entity = u` is comparing the `entity` field of `AuditEventUser`, which is an object of `User` type, with the `u` field of `User`, which is an object of `User` type.

To fix this issue, we need to explicitly specify the join condition using the `id` field of the `User` class. This can be done by changing the query to:

“`
@Query(“SELECT MAX(h.eventInstant) FROM User u JOIN AuditEventUser a ON a.entity.id = u.id JOIN a.eventHistory h WHERE u.username = :username AND a.event = :event”)
Instant getUserEventInstant(@Param(“username”) String username, @Param(“event”) UserEventType event);
“`

This query will now correctly compare the `id` fields of the `User` and `AuditEventUser` objects, and the error should be resolved.

Q&A

Ran into a validation issue comparing left expression of type AbstractEntity with right expression of type User in JPQL query. How do I resolve it?

In Hibernate 8.x, join statements require the same data type. Either modify the query or use TREAT to cast the entity to the desired type.

In a query, want to find the max event timestamp for a user based on their username and a specific event type. How can I modify the query to work in Hibernate 8.x?

Refactor the query to use TREAT to cast the entity to the User type. This ensures both sides of the join have the same data type.

Video Explanation:

The following video, titled "Table Extraction With Infinite Scrolling In UiPath - Full Tutorial ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

... compare the results and keep scrolling until we're at the bottom of the page. The best practice is always to ensure we validate the data ...