복붙노트

[SPRING] Spring 부트 2.0.0 이후의 "튜플과 앨리어스의 크기가 다릅니다"예외.

SPRING

Spring 부트 2.0.0 이후의 "튜플과 앨리어스의 크기가 다릅니다"예외.

//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, namedquery 리턴 유형입니다.

// 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);

}

이것은 저장소 클래스입니다.

이 namednativequeries를 사용하여 저장 프로 시저에서 엔티티가 아닌 pojos를 반환합니다. 스프링 부트 1.5.9 이후 예외없이 작동했습니다. 스프링 부트 2.0.0.M7. 2.0.0.RELEASE로 마이그레이션 한 후 다음 예외가 발생하기 시작했습니다.

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]

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

해결법

  1. ==============================

    1.jpa 2.1에서 저장소 인터페이스 메서드에 @Query (nativeQuery = true) 주석을 추가하여이 문제를 해결했습니다. 참고:

    jpa 2.1에서 저장소 인터페이스 메서드에 @Query (nativeQuery = true) 주석을 추가하여이 문제를 해결했습니다. 참고:

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

  2. ==============================

    2.SqlResultSetMappings를로 변경하십시오.

    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();
    }
    
  3. ==============================

    3.한 가지 더 많은 해결책을 찾았습니다. getStat ()의 List에서 generic을 제거하면됩니다.

    한 가지 더 많은 해결책을 찾았습니다. 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);
    }
    
  4. ==============================

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

    이를 해결하는 방법에는 여러 가지가 있으며, 대부분 다른 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);
    
    }
    
  5. ==============================

    5.Spring Data JPA의 문제점 보고서라고 생각합니다. https://jira.spring.io/browse/DATAJPA-1280

    Spring Data JPA의 문제점 보고서라고 생각합니다. https://jira.spring.io/browse/DATAJPA-1280

    이 문제를 해결하기 위해 Spring Data release train Kay-SR4로 다운 그레이드 할 수 있습니다 (SR5는 최신 최신 버전이며 Spring Boot 2.0.0에서 사용되는 버전입니다). 그냥 추가 :

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

    pom.xml 섹션에 추가하십시오.

  6. ==============================

    6.이제 버그가 수정되었습니다. jira.spring.io/browse/DATAJPA-1280

    이제 버그가 수정되었습니다. jira.spring.io/browse/DATAJPA-1280

    더하다:

    @Query(nativeQuery=true) 
    

    저장소의 새로운 메소드의 맨 위에.

  7. ==============================

    7.다른 사람들이 지적했듯이, 이것은 Spring Boot 2.0.0에서 소개되었고 DATAJPA-1280에서보고 된 버그입니다.

    다른 사람들이 지적했듯이, 이것은 Spring Boot 2.0.0에서 소개되었고 DATAJPA-1280에서보고 된 버그입니다.

    Spring Boot 2.0.3에서 수정되어 발표되었습니다.

  8. from https://stackoverflow.com/questions/49056084/got-different-size-of-tuples-and-aliases-exception-after-spring-boot-2-0-0-rel by cc-by-sa and MIT license