Hibernate criteria implementation for this entity model (subquery, self-join)

穿精又带淫゛_ 提交于 2019-12-11 21:08:12

问题


Given the following entity one-to-many model:

One Repository can be linked to many AuditRecords.

Many AuditRecords can all link to the same Repository

@Entity
class AuditRecordEntity {
  private AuditRepositoryEntity auditRepository;  

  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = AUDIT_REPOSITORY_DB_COLUMN_NAME, nullable = false, updatable = false)
  public AuditRepositoryEntity getAuditRepository() {
    return auditRepository;
  }
  ...
}

@Entity
class AuditRepositoryEntity {
  private List<AuditRecordEntity> auditRecords = new ArrayList<AuditRecordEntity>();

  @OneToMany(mappedBy = "auditRepository")
  public List<AuditRecordEntity> getAuditRecords() {
    return auditRecords;
  }
  ...
}

Minor correction, in ERD diagram below, for 'repositoryId', read 'auditRepository'

I am trying to get the Criteria API implementation to:

Get the latest (by accessTime) AuditRecord for each distinct Repository? I.e. a list of AuditRecords, one for each Repository, where the AuditRecord is the last AuditRecord for that Repository (in the case where a Repository has many AuditRecords).

I have the HQL query to do this:

select auditRecord from AuditRecordEntity auditRecord where auditRecord.accessTime = 
(select max(auditRecord2.accessTime) from AuditRecordEntity auditRecord2 where  
auditRecord2.auditRepository = auditRecord.auditRepository)

But need to use the Criteria APi instead:

CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Object> query = builder.createQuery();
Root<AuditRecordEntity> root = query.from(AuditRecordEntity.class);
// what next?

回答1:


I have got this to work(around) by using the output from the HQL query as input to the criteria API:

final List<UUID> auditRecordIds = execute("select auditRecord from AuditRecordEntity auditRecord where auditRecord.accessTime = 
(select max(auditRecord2.accessTime) from AuditRecordEntity auditRecord2 where  
auditRecord2.auditRepository = auditRecord.auditRepository)")

Root<AuditRecordEntity> root = criteriaQuery.from(AuditRecordEntity.class);
criteriaQuery.select(root);

List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(root.get("id").in(auditRecordIds.toArray()));
entitySearchCriteria.addPredicates(predicates);
...


来源:https://stackoverflow.com/questions/24919038/hibernate-criteria-implementation-for-this-entity-model-subquery-self-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!