简体   繁体   English

JPA 和 Spring 引导:integer 来自 DB (H2) 未按预期映射到 Z84E2C64F38F78BAZEA5C64F38F78BAZEA5

[英]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.我正在重构 Spring Boot 2.3.1 应用程序的一部分,以前的开发人员在其中使用 Integer 类型(值为 0 或 1)而不是代码中的任何位置的 boolean。

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:但我注意到了一些我没想到的事情:我还更改了实体 class 中的字段类型,当从数据库加载它时,出现错误:

[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.使用 H2 运行现有测试时会发生这种情况。

the field created by Liquibase at test start up is: Liquibase 在测试启动时创建的字段是:

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:在 orm.xml 中,我有这个简单的映射:

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

My repository class is:我的存储库 class 是:

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...我已经尝试了几件事(使 Java 字段 boolean 而不是 Boolean,声明具有各种类型的列,如 NUMBER(1,0),但无用...

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. 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?所以在某种程度上,我的重构已经在改进代码:字段不是 boolean 的唯一地方是实体 class.. 但它强制为映射添加额外代码......这应该直接工作,正确的?

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 !任何帮助将不胜感激,谢谢!

as it could be expected, it was a stupid mistake...正如所料,这是一个愚蠢的错误......

there was a method in the CrudRepository I have:我在 CrudRepository 中有一个方法:

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

for which the field type needed to be changed to boolean:需要将字段类型更改为 boolean 的字段类型:

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

That's what the error message was about !这就是错误消息的内容!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM