I had the very same problem: COALESCE works with Postgress and it crashs the same exception with H2 database, so I created a workaround implementing two repositories interfaces (Product entity) and used annotation @profile, then in compilation time the correct query will be built.
First of all I created a base repository interface without extends no other interface:
public interface ProductRepositoryBase {
Page<Product> findCustomized(List<Category> categories, String name, Pageable page);
Optional<Product> findById(Long id);
Product save(Product entity);
void deleteById(Long id);
}
Then I created two other interfaces (one for each profile), one for development with postgres db (dev):
@Profile("dev")
public interface ProductRepositoryDev extends ProductRepositoryBase,JpaRepository<Product, Long> {
@Query("SELECT DISTINCT obj FROM Product obj INNER JOIN obj.categories cats "
+ "WHERE (COALESCE(:categories,null) IS NULL OR cats IN :categories) AND "
+ "(LOWER(obj.name) LIKE LOWER(CONCAT('%',:name,'%' )))")
Page<Product> findCustomized(List<Category> categories, String name, Pageable page);
}
And another for test (where H2 database is used):
@Profile("test")
public interface ProductRepositoryTest extends ProductRepositoryBase,JpaRepository<Product, Long> {
@Query("SELECT DISTINCT obj FROM Product obj INNER JOIN obj.categories cats "
+ "WHERE (:categories IS NULL OR cats IN :categories) AND "
+ "(LOWER(obj.name) LIKE LOWER(CONCAT('%',:name,'%' )))")
Page<Product> findCustomized(List<Category> categories, String name, Pageable page);
}
Note that my problematic query was associated with findCustomized
method, but in the base interface you must declare any other repository ,method you use in the Product entity service layer, otherwise when running the code it will crash as these functions are not defined in the base interface.
Also in the service layer you need to declare the base interface
@Service
public class ProductService {
@Autowired
private ProductRepositoryBase productRepository;
Another note: It seems that Spring Boot has tagged COALESCE as deprecated, a colegue of mine tested for Spring Boot 2.4.4 the query with COALESCE with H2 and it worked fine, but as I´m using 2.7.3 it raises the exception. Anyway the query writen in @Profile("test") worked fine for both databases (H2 and postgres).