Реализация критериев гибернации для этой модели объекта (подзапрос, самосоединение)

Учитывая следующую модель объекта «один ко многим»:

Один репозиторий может быть связан со многими 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;
  }
  ...
}

Незначительное исправление на диаграмме ERD ниже для «repositoryId» читать «auditRepository».

Я пытаюсь реализовать реализацию Criteria API для:

Получить последнюю (по времени доступа) AuditRecord для каждого отдельного репозитория? Т.е. список записей аудита, по одной для каждого репозитория, где запись аудита является последней записью аудита для этого репозитория (в случае, если в репозитории много записей аудита).

У меня есть запрос 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?

person user2586917    schedule 23.07.2014    source источник
comment
У вас есть файл hibernate.hbm.xml для AuditRecordEntity.class с отношениями?   -  person hurricane    schedule 24.07.2014
comment
Сообщение @hurricane обновлено.   -  person user2586917    schedule 24.07.2014


Ответы (1)


У меня есть это для работы (вокруг), используя вывод запроса 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);
...
person user2586917    schedule 24.07.2014