Skip to content
Advertisement

JPA and Spring Boot : integer from DB (H2) doesn’t get mapped to boolean as expected

I am refactoring part of an Spring Boot 2.3.1 application, in which previous developers have used Integer type (with values 0 or 1) instead of boolean a bit everywhere in the code.

But I am noticing something I didn’t expect : I’ve also changed the field type in the entity class, and when loading it from the DB, I get an error :

[2021-05-04T22:27:36.036Z] [main] [24] [ERROR] Parameter value [0] did not match expected type [java.lang.Boolean (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [0] did not match expected type [java.lang.Boolean (n/a)]
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [0] did not match expected type [java.lang.Boolean (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [0] did not match expected type [java.lang.Boolean (n/a)]
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy247.findByTicketIdAndInternalComment(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
    at com.sun.proxy.$Proxy162.findByTicketIdAndInternalComment(Unknown Source) 

This happens when running the existing tests, with H2.

the field created by Liquibase at test start up is :

INTERNAL_COMMENT BOOLEAN DEFAULT TRUE

my field used to be :

private Integer internalComment;

and it was working.

Now it’s :

private Boolean internalComment;

and it’s not working.

In the orm.xml, I have this simple mapping :

        <basic name="internalComment">
            <column name="INTERNAL_COMMENT" nullable="true" />
        </basic> 

My repository class is :

public interface JpaCommentEntityRepository
    extends CrudRepository<TicketCommentEntity, Long>, JpaSpecificationExecutor<TicketCommentEntity>

I’ve tried several things (making the Java field boolean instead of Boolean, declaring the column with various types like NUMBER(1,0)), but to no avail…

The only thing that works is when I change back to Integer, and perform a manual mapping to boolean when creating my domain object from the entit class.. So at least, I am sure this is the field causing problem, and not something else.

So in a way, my refactoring is already improving the code : the only place where the field is not a boolean is in the entity class.. but it forces be to add extra code for the mapping… and this should work directly, right ?

So I guess I am missing something, but I am running out of ideas on how to investigate / fix this.

Any help would be much appreciated, thanks !

Advertisement

Answer

as it could be expected, it was a stupid mistake…

there was a method in the CrudRepository I have :

@Nonnull
List<TicketCommentEntity> findByTicketIdAndInternalComment(long ticketId, Integer internalComment);

for which the field type needed to be changed to boolean :

@Nonnull
List<TicketCommentEntity> findByTicketIdAndInternalComment(long ticketId,boolean internalComment);

That’s what the error message was about !

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement