source

Spring Boot 2.0.0.REASE 마이그레이션 후 "다른 크기의 튜플 및 별칭을 가져왔습니다" 예외

gigabyte 2023. 7. 18. 23:10
반응형

Spring Boot 2.0.0.REASE 마이그레이션 후 "다른 크기의 튜플 및 별칭을 가져왔습니다" 예외

//imports, etc.

@Entity
@Table(name = "TSTRANS")
@SqlResultSetMappings(
        {                   
                @SqlResultSetMapping(name = TS_TRANS_EMP_STAT,
                        classes = {
                                @ConstructorResult(
                                        targetClass = EmpStat.class,
                                        columns = {
                                                @ColumnResult(name = "EMPID", type = Long.class),
                                                @ColumnResult(name = "CODE", type = String.class),
                                                @ColumnResult(name = "TOTALCOUNT", type = Integer.class)
                                        }
                                )
                        })
        }
)
@NamedNativeQueries({
        @NamedNativeQuery(name = "TsTrans.getStat", query = "select * from SP_TASK_STATS_EMP  (:in_empid, :in_gidstr, :in_onlytodo)", resultSetMapping = TS_TRANS_EMP_STAT)
})
public class TsTrans extends TsTransCommon {
    public static final String TSTRANS_BADGE = "TSTRANS_BADGE";

    private static final long serialVersionUID = -3391028108003625153L;
    public static final String TS_TRANS_EMP_STAT = "TsTrans.empStat";
    public static final String TS_TRANS_SCHEDULE_STAT = "TsTrans.getScheduleStat";
    public static final String TS_TRANS_FOLLOWUP = "TS_TRANS_FOLLOWUP";
}

이것이 실체입니다.

// imports, etc.

public class EmpStat extends BaseStat {

    private static final long serialVersionUID = -4410895509438727581L;
    private Long mEmpid;

    public EmpStat(Long aEmpid, String aCode, Integer aTotalcount) {
        super(aCode, aTotalcount);
        mEmpid = aEmpid;
    }

    public Long getEmpid() {
        return mEmpid;
    }

    public void setEmpid(Long aEmpid) {
        mEmpid = aEmpid;
    }
}

이것은 쿼리 반환 유형으로 명명된 비엔티티 pojo입니다.

// imports, etc.

@Repository
public interface TsTransRepository extends TsTransCommonRepository<TsTrans> {
    List<EmpStat> getStat(@Param("in_empid") Long aEmpid, @Param("in_gidstr") String aGidstr, @Param("in_onlytodo") Boolean aOnlytodo);

}

이것은 리포지토리 클래스입니다.

명명된 네이티브 쿼리를 사용하여 저장 프로시저에서 엔티티가 아닌 포조를 반환합니다.Spring Boot 1.5.9부터 예외 없이 작동하고 있습니다.그리고 Spring Boot 2.0.0에서.M7. 2.0.0.REASE로 마이그레이션한 후 다음과 같은 예외가 발생하기 시작했습니다.

org.hibernate.HibernateException: Got different size of tuples and aliases
    at org.hibernate.jpa.spi.NativeQueryTupleTransformer$NativeTupleImpl.<init>(NativeQueryTupleTransformer.java:68) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.jpa.spi.NativeQueryTupleTransformer.transformTuple(NativeQueryTupleTransformer.java:28) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:85) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.custom.CustomLoader.getResultList(CustomLoader.java:430) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.Loader.list(Loader.java:2502) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2161) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1016) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:152) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.query.Query.getResultList(Query.java:146) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129) ~[spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91) ~[spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136) ~[spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125) ~[spring-data-jpa-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]

마이그레이션 중에 뭔가를 놓쳤습니까?

jpa 2.1 퍼팅에서@Query(nativeQuery = true)리포지토리 인터페이스 메서드에 대한 주석으로 문제를 해결했습니다.참조:

https://github.com/spring-projects/spring-data-examples/tree/master/jpa/jpa21#support-for-custom-sqlresultsetmapping-with-constructorresult

버그였는데, 이제 수정되었습니다: jira.spring.io/browse/DATAJPA-1280

추가:

@Query(nativeQuery=true) 

저장소에 있는 새 메서드의 맨 위에 있습니다.

변경 내용SqlResultSetMappings로.

@SqlResultSetMappings({
    @SqlResultSetMapping(name = TS_TRANS_EMP_STAT,
        columns = {
            @ColumnResult(name = "EMPID", type = Long.class),
            @ColumnResult(name = "CODE", type = String.class),
            @ColumnResult(name = "TOTALCOUNT", type = Integer.class)
        })
}

그리고 변화EmpStat일반 클래스에서 인터페이스로:

public interface EmpStat {
    Long getEMPID();
    String getCODE();
    Integer getTOTALCOUNT();
}

해결책을 하나 더 찾았습니다. getStat()의 List에서 generic을 제거하면 됩니다.

@Repository
public interface TsTransRepository extends TsTransCommonRepository<TsTrans> {
    List getStat(@Param("in_empid") Long aEmpid, @Param("in_gidstr") String aGidstr, @Param("in_onlytodo") Boolean aOnlytodo);
}

이를 해결하는 방법은 여러 가지가 있으며, 대부분 다양한 jpa 및 스프링 데이터 기능의 조합입니다.저는 몇 가지 조사를 해서 https://jira.spring.io/browse/DATAJPA-1280 발행에 추가했습니다.무엇을 할 수 있는지 알아보려면 이 프로젝트 https://github.com/EugeneNik/spring-data-datajpa-1280-example 을 보고 현재 어떤 접근 방식이 잘 작동하는지 테스트를 실행하십시오.현재 코드 변경 없이 마이그레이션을 수행할 수 있는 방법은 없지만 가장 간단한 방법은 리포지토리 방법에 클래스 투영 선언을 추가하는 것입니다.모든 매핑을 변경할 필요는 없지만 리포지토리 호출도 변경해야 합니다.문제를 해결하는 또 다른 방법일 뿐입니다.

@Repository
public interface TsTransRepository extends TsTransCommonRepository<TsTrans> 
{
    <T> List<T> getStat(@Param("in_empid") Long aEmpid, 
@Param("in_gidstr") String aGidstr, @Param("in_onlytodo") Boolean aOnlytodo, Class<T> beanProjection);

}

Spring Data JPA: https://jira.spring.io/browse/DATAJPA-1280 의 이슈 보고서인 것 같습니다.

해결 방법으로 Spring Data 릴리스 트레인 Kay-SR4(SR5는 현재 최신 버전이며 Spring Boot 2.0.0에서 사용되는 버전임)로 다운그레이드할 수 있습니다.추가만 하면 됩니다.

<spring-data-releasetrain.version>Kay-SR4</spring-data-releasetrain.version>

당신의 pom.xml에.<properties>부분.

다른 사람들이 지적했듯이, 이 버그는 Spring Boot 2.0.0에 도입되었고 DATAJPA-1280에 보고되었습니다.

Spring Boot 2.0.3에서 수정 및 릴리스되었습니다.

언급URL : https://stackoverflow.com/questions/49056084/got-different-size-of-tuples-and-aliases-exception-after-spring-boot-2-0-0-rel

반응형