此实体模型的Hibernate条件实现(子查询,自连接)

时间:2014-07-23 19:16:09

标签: java hibernate criteria criteria-api hibernate-criteria

给出以下实体一对多模型:

一个存储库可以链接到许多AuditRecords。

许多AuditRecords都可以链接到同一个存储库

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

对于'repositoryId',在下面的ERD图中进行小修正,读为'auditRepository'

我正在尝试将Criteria API实现:

为每个不同的存储库获取最新的(通过accessTime)AuditRecord吗? I.e。一个AuditRecords列表,每个Repository一个,其中AuditRecord是该Repository的最后一个AuditRecord(在Repository有许多AuditRecords的情况下)。

我有HQL查询来执行此操作:

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

但需要使用Criteria APi代替:

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

1 个答案:

答案 0 :(得分:0)

我通过使用HQL查询的输出作为条件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);
...