在主键上定义的JPA条件不起作用

时间:2017-04-22 09:34:12

标签: jpa query-builder criteria-api

我有一个使用' Id'和' updatedDate'作为复合主键。当我使用这两个属性中的任何一个构建查询时,我得到以下错误:

  

引起:java.lang.IllegalArgumentException:无法解析路径

的属性[id]

我的查询

      @Override
      public MyEntityInterface find(final Long Id) {
      final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
      final CriteriaQuery<MyEntity> query = criteriaBuilder.createQuery(this.entityClass);
      final Root<MyEntity> root = query.from(this.entityClass);
      query.where(criteriaBuilder.equal(root.get(MyEntity.ID_FIELD), Id));
      query.orderBy(criteriaBuilder.desc(root.get(MyEntity.UPDATED_DATE_FIELD)));
      try {
          return this.entityManager.createQuery(query).getSingleResult();
      } catch (final NoResultException e) {
          return null;
      }

我的实体类

@Entity
@Table(name = "my_sample_table")
@IdClass(MyEntityKey.class)
public class MyEntity implements Serializable, MyEntityInterface,EntityCopySupport<MyEntityInterface> {

private static final long serialVersionUID = 1L;
public static final String ID_FIELD = "id";
public static final String UPDATED_DATE_FIELD = "updatedDate";
public static final String UPDATED_BY_FIELD = "updatedBy";

@Id
@Column(name = "id", nullable = false)
private Long id;

@Id
@Column(name = "updated_date", nullable=false)
private Date updatedDate;

@Column(name = "name")
private String name;

@Column(name = "updated_by")
private String updatedBy;

@PrePersist
public void updateDate () {
    updatedDate = new Date();
}

@Override
public Long getId() {
    return this.id;
}

@Override
public void setId(Long id) {
    this.id = id;
}

@Override
public Date getUpdatedDate() {
    return this.updatedDate;
}

@Override
public void setUpdatedDate(Date updatedDate) {
    this.updatedDate = updatedDate;
}

@Override
public String getName() {
    return this.name;
}

@Override
public void setName(String name) {
    this.name = name;
}

@Override
public String getUpdatedBy() {
    return this.updatedBy;
}

@Override
public void setUpdatedBy(String updatedBy) {
    this.updatedBy = updatedBy;
}

@Override
public void copy(MyEntityInterface source) {
    this.setId(source.getId());
    this.setName(source.getName());
    this.setUpdatedBy(source.getUpdatedBy());
}

}

我的ID类:

public class MyEntityKey implements Serializable {

private static final long serialVersionUID = 1L;
private Long id;
private Date updatedDate;

public MyEntityKey() {}

public MyEntityKey(Long id, Date updatedDate) {
    super();
    this.id = id;
    this.updatedDate = updatedDate;
}

public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public Date getUpdatedDate() {
    return updatedDate;
}
public void setUpdatedDate(Date updatedDate) {
    this.updatedDate = updatedDate;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((updatedDate == null) ? 0 : updatedDate.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    MyEntityKey other = (MyEntityKey) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (updatedDate == null) {
        if (other.updatedDate != null)
            return false;
    } else if (!updatedDate.equals(other.updatedDate))
        return false;
    return true;
}
}

当我的查询条件被修改为忽略&#39; Id&#39;和&#39; updatedDate&#39;属性,它工作正常 - 下面是可以正常工作的查询

          @Override
          public MyEntityInterface find(final Long Id) {
          final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
          final CriteriaQuery<MyEntity> query = criteriaBuilder.createQuery(this.entityClass);
          final Root<MyEntity> root = query.from(this.entityClass);
          query.where(criteriaBuilder.equal(root.get(MyEntity.UPDATED_BY_FIELD), "user"));
          try {
              return this.entityManager.createQuery(query).getSingleResult();
          } catch (final NoResultException e) {
              return null;
          }

对查询进行硬编码也可以正常工作,如下所示:

    Query query = entityManager.createQuery("SELECT entity FROM MyEntity entity WHERE entity.id = ? ORDER BY entity.updatedDate DESC");
    query.setParameter(1, Id);
    return (MyEntity) query.setMaxResults(1).getSingleResult();

我试图浏览网站以查找此问题,但其他帖子中提供的解决方案更具体针对所提出的问题。如果您需要更多信息,请告诉我。谢谢!

0 个答案:

没有答案