카테고리 없음

Hibernate 4.3.1.Final에서 5.4.27.Final로 Spring 애플리케이션 마이그레이션

기록만이살길 2021. 2. 26. 04:20
반응형

Hibernate 4.3.1.Final에서 5.4.27.Final로 Spring 애플리케이션 마이그레이션

1. 질문(문제점):

나는 오래된 Spring 애플리케이션에서 최대 절전 모드 4.3.1.Final에서 5.4.27.Final로 마이그레이션하려고합니다 (대부분의 Spring 구성 요소는 버전 4.3.13.Final에 있습니다). 몇 가지 사소한 문제 (클래스 가져 오기)를 수정하고 maven으로 애플리케이션을 빌드 한 후 Tomcat 7.0.107 (루트 예외를 가리키는 스택 추적의 일부)에이 웹 애플리케이션을 배포하는 동안 다음 오류가 발생합니다.

2121 Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List hr.chus.plus.dao.repository.StatusUpdateRepository     .findAlarmLogsByZoneAndDatesAndNeedsAck(java.lang.Integer,java.lang.String,java.util.Date,java.util.Date)!
-- cut --
2150 Caused by: org.hibernate.QueryException: Could not resolve identifier `acks` as plural-attribute [FROM hr.chus.plus.dao.model.jpa.StatusUpdate WHERE updateType='ALARM'        AND relatedId=:alarmId   AND subtype='ZONE'   AND subtypeUuid=:zone   AND timestamp BETWEEN :start AND :end  AND needAck=true   AND size(acks)=0]
2151   at org.hibernate.QueryException.generateQueryException(QueryException.java:120) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2152   at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2153   at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2154   at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2155   at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2156   at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2157   at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2158   at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2159   at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
2160   ... 79 common frames omitted
2161 Caused by: org.hibernate.QueryException: Could not resolve identifier `acks` as plural-attribute
2162   at org.hibernate.hql.internal.ast.tree.CollectionPathNode.from(CollectionPathNode.java:123) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]

이 JPQL은 이전 버전에서 잘 실행되고 배포되었습니다.

언급 된 엔티티의 관련 부분은 다음과 같습니다.

AlarmLog :

@Entity
@Table(name = "z_alarm_log")
@SecondaryTable(name = "z_alarm_log_data", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "id") })
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class AlarmLog extends AbstractLogEntity {

private static final int SUBTYPE_MAX_LENGTH = 10;

  @Column(name = "alarm_id")
  private Integer          alarmId;

  @Column(name = "trouble", columnDefinition = "TINYINT")
  private Boolean          trouble;

  @Lob
  @Basic(fetch = FetchType.EAGER)
  @Column(name = "data", columnDefinition = "BLOB", table = "z_alarm_log_data")
  private String           data;

  @Column(name = "need_ack", columnDefinition = "TINYINT")
  private Boolean          needAck            = false;

  @OneToMany(mappedBy = "log", fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
  private Set<AlarmLogAck> acks               = new HashSet<>();

  @Column(name = "code", nullable = false)
  private int              code               = 0;

  @Column(name = "subtype", length = SUBTYPE_MAX_LENGTH)
  private String           subtype;

  @Column(name = "subtype_id")
  private Integer          subtypeId;

  @Column(name = "subtype_uuid", nullable = true, columnDefinition = "CHAR")
  private String           subtypeUuid;

AlarmLogAck :

@Entity
@Table(name = "z_alarm_log_ack")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AlarmLogAck extends AbstractLongIdEntity {
  private static final int MESSAGE_MAX_LENGTH = 200;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "zipato_id")
  private Zipato           zipato;

  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "log_id")
  private AlarmLog         log;

  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "user_id")
  private User             user;

  @Column(name = "show_date", nullable = false, columnDefinition = "DATETIME")
  private Date             showDate;

  @Column(name = "ack_date", nullable = true, columnDefinition = "DATETIME")
  private Date             ackDate;

  @Column(name = "message", length = MESSAGE_MAX_LENGTH, nullable = true)
  private String           message;

AlarmLogRepository :

  @Transactional(readOnly = true)
  public interface AlarmLogRepository extends JpaRepository<AlarmLog, Long>, JpaSpecificationExecutor<AlarmLog> {

    @Query("FROM AlarmLog " + //
        "WHERE zipato=:zipato " + //
        "  AND alarmId=:alarmId " + //
        "  AND subtype='ZONE' " + //
        "  AND subtypeUuid=:zone " + //
        "  AND timestamp BETWEEN :start AND :end" + //
        "  AND needAck=true " + //
        "  AND size(AlarmLog.acks)=0")
    List<AlarmLog> findAlarmLogsByZoneAndDatesAndNeedsAck(@Param("zipato") Zipato p_zipato,
                                                          @Param("alarmId") Integer p_alarmId,
                                                          @Param("zone") String p_zone,
                                                          @Param("start") Date p_start,
                                                          @Param("end") Date p_end);

이 오류 검색을 시도했지만 plural-attribute인식되지 않는 정확한 조합을 찾을 수 없습니다 . 또한 특정 수준으로 디버깅을 시도한 결과 이것이 Set컬렉션 유형 acks Set으로 인식되지 않거나 목록에 없으므로 plural-attribute.

나는 이것을 고치는 방법을 잃어 버렸다 ...

어떤 아이디어?

2. 해결방안:

해당 쿼리의 경우 엔터티에 대한 식별자를 설정 AlarmLog하고 다음과 같은 방식으로 where 조건에서 해당 식별자를 사용해야합니다.

...
@Query("FROM AlarmLog al " +
        "WHERE zipato=:zipato " +
        "  AND alarmId=:alarmId " +
        "  AND subtype='ZONE' " +
        "  AND subtypeUuid=:zone " + 
        "  AND timestamp BETWEEN :start AND :end" +
        "  AND needAck=true " + 
        "  AND size(al.acks)=0")
...

65787956
반응형