1

I'm using Spring Boot and Hibernate and when running my tests in H2 (2.1.210) I get an Values of types "BOOLEAN" and "INTEGER" are not comparable error. This is due to a @Query comparing a boolean to an integer. This works in Oracle correctly.

@Query("FROM TABLE_NAME t WHERE t.value= 0")
public List<Example> findExample();

t.value is of type Boolean.

I've found other questions with similar issues and the recommendation is to add this.

import org.hibernate.dialect.H2Dialect;

public class H2DialectExtended extends H2Dialect {

    @Override
    public String toBooleanValueString(boolean bool) {
        return bool ? "TRUE" : "FALSE";
    }
}

However this doesn't work.

How can I solve this?

H2/Hibernate Settings - application.yml

spring:

  driver:
    class-name: org.h2.Driver

  datasource:
    platform:
      url: jdbc:h2:mem:project_name;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;
      username: username
      password:

  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect
4
  • 1
    Oracle does not have a BOOLEAN data type in SQL. It does have a BOOLEAN data type in PL/SQL (but your query appears to be SQL and not PL/SQL). Commented Mar 14, 2022 at 13:07
  • The query works correctly in Oracle. It must map t.value to 0 or 1. It just doesn't work in H2. Commented Mar 14, 2022 at 13:08
  • My point is that when you say "This is due to a @Query comparing a boolean to an integer." cannot be correct as Oracle does not have BOOLEAN data type in SQL so, inside the database, you are probably comparing an integer to an integer. Commented Mar 14, 2022 at 13:09
  • In my object value is of type Boolean. In the database it will be stored as 0 or 1 but Hibernate must be mapping it based on the dialect. I believe my statement is correct as I'm not saying Oracle has a boolean type. I'm saying that my code is essentially running "TRUE" = 1 instead of mapping the values first. When executed in Oracle it runs 1 = 1 as expected. I've updated my question to make it clearer. Commented Mar 14, 2022 at 13:16

1 Answer 1

1

If this @Query("FROM TABLE_NAME t WHERE t.value= 0") is exactly what you have, then it means that this is JPQL language, not SQL language. The way that you compare it, it is like the entity related with this has a integer field, which should not be the case. The Java field should have been boolean.

Then this should have been @Query("FROM TABLE_NAME t WHERE t.value= false") and it would be able to work both for Oracle and H2.

By default, when you use an ORM vendor like Hibernate and you have an Oracle database, the entity field boolean value will be matched in database level with type of Number(1) where 0 == false and 1 == true on ORM layer.

One way for this to work would be to have your entity field as the following:

@Type(type= "org.hibernate.type.NumericBooleanType")
private Boolean value;
Sign up to request clarification or add additional context in comments.

10 Comments

This sounds like what I want although I'm having some trouble with it. If I use t.value = false I still get the same error. I've also tried setting the @Type for the variable. In the exception I can see it's converting the false to 0. E.g tableName.value=0
@Michael do you get the same exception message with @Type(type= "org.hibernate.type.NumericBooleanType") ?
Yes the same message with @Type added. If I change it to t.value = false or t.value = 0 it throws the same exception in both cases.
@Michael please share the properties that you use for test, in order to set h2 in Oracle mode
I upgraded to Hibernate 5.6.5 and the changes you mentioned solved it! I didn't need the @Type annotations but changing t.value=0 to t.value=false worked nicely.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.