微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 Spring 应用程序从 Hibernate 4.3.1.Final 迁移到 5.4.27.Final

如何解决将 Spring 应用程序从 Hibernate 4.3.1.Final 迁移到 5.4.27.Final

我正在尝试在旧的 Spring 应用程序中从 hibernate 4.3.1.Final 迁移到 5.4.27.Final(大多数 Spring 组件都在 4.3.13.Final 版本上)。更新版本修复几个小问题(类导入)并使用 maven 构建应用程序后,我在尝试在 Tomcat 7.0.107 上部署此 Web 应用程序时出现以下错误(堆栈跟踪的一部分指向根异常):>

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 在之前的版本中运行和部署良好。

上述实体的相关部分如下:

报警日志:

@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;

报警日志确认:

@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",columnDeFinition = "DATETIME")
  private Date             ackDate;

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

报警日志存储库:

  @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

我不知道如何解决这个问题...

有什么想法吗?

解决方法

对于该查询,您应该为实体 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")
...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。