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 !