CriteriaQuery JOIN
Помогите, пожалуйста, составить запрос типа:
select dmp_id, dmp_dr_id, dmp_permit_id, dmp_dsc,
p.name as permit_name,
from dat_map_permit dmp
join permit p on p.id = dmp_permit_id
where dmp.dmp_dr_id = ?
Не могу понять где будет определён join permit p on p.id = dmp_permit_id. Мой запрос:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MapPermitDto> cq = cb.createQuery(MapPermitDto.class);
Root<MapPermitEntity> root = cq.from(MapPermitEntity.class);
Join<MapPermitEntity, PermitEntity> permitIdJoin = root.join(MapPermitEntity_.permId);
cq.multiselect(
root.get(MapPermitEntity_.id).alias(MapPermitEntity_.ID),
root.get(MapPermitEntity_.drid).alias(MapPermitEntity_.DRID),
root.get(MapPermitEntity_.permid).alias(MapPermitEntity_.PERMID),
root.get(MapPermitEntity_.dsc).alias(MapPermitEntity_.DSC),
permitIdJoin.get(PermitEntity_.name).alias("permitName"));
cq.where(cb.equal(root.get(MapPermitEntity_.DRID), mapPermitDto.getDrid()));
Ответы (2 шт):
Автор решения: kent
→ Ссылка
В принципе было всё правильно, но в DTO было несовпадение типа данных.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MapPermitDto> cq = cb.createQuery(MapPermitDto.class);
Root<MapPermitEntity> root = cq.from(MapPermitEntity.class);
Join<MapPermitEntity, PermitEntity> permitIdJoin = root.join(MapPermitEntity_.permId);
cq.multiselect(
root.get(MapPermitEntity_.id).alias(MapPermitEntity_.ID),
root.get(MapPermitEntity_.drid).alias(MapPermitEntity_.DRID),
root.get(MapPermitEntity_.permid).alias(MapPermitEntity_.PERMID),
root.get(MapPermitEntity_.valb).alias(MapPermitEntity_.VALB),
root.get(MapPermitEntity_.vali).alias(MapPermitEntity_.VALI),
root.get(MapPermitEntity_.valc).alias(MapPermitEntity_.VALC),
root.get(MapPermitEntity_.dsc).alias(MapPermitEntity_.DSC),
permitIdJoin.get(PermitEntity_.name).alias(PermitEntity_.NAME),
permitIdJoin.get(PermitEntity_.dsc).alias("permDsc"),
permitIdJoin.get(PermitEntity_.rModulesid).alias(PermitEntity_.R_MODULESID),
permitIdJoin.get(PermitEntity_.typ).alias(PermitEntity_.TYP)
);
cq.where(cb.equal(root.get(MapPermitEntity_.DRID), mapPermitDto.getDrid()));
try {
return em.createQuery(cq).getResultList();
} catch (NoResultException e) {
return null;
}
Автор решения: amala
→ Ссылка
Не могу понять где будет определён join permit p on p.id = dmp_permit_id.
Насколько я понял поле присоединяемой таблицы определяется через JPA-связь (например, @OneToOne).
Если попытаться присоединить таблицу по полю без JPA-связи, то Criteria API бросает исключение org.hibernate.query.criteria.internal.BasicPathUsageException
Мой код
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<DTO> dmpCriteria = cb.createQuery(DTO.class);
Root<DMP> dmpRoot = dmpCriteria.from(DMP.class);
Join<DMP, Permit> tasks = dmpRoot.join("dmp_permit_id");
dmpCriteria.where(cb.equal(dmpRoot.get("dmp_dr_id"), 3));
Join<DMP, Permit> permitIdJoin = dmpRoot.join("dmp_permit_id");
dmpCriteria.multiselect(
dmpRoot.get("dmp_id"),
dmpRoot.get("dmp_dr_id"),
dmpRoot.get("dmp_permit_id"),
dmpRoot.get("dsc"),
permitIdJoin.get("id")
);
TypedQuery<DTO>t = s.createQuery(dmpCriteria);
List<DTO> dmpList = t.getResultList();
Сущности
MapPermitEntity
@Entity
@Table(name = "dmp_map_permit")
public class DMP {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long dmp_id;
private Long dmp_dr_id;
private String dsc;
@OneToOne
@JoinColumn(name = "dmp_permit_id")
private Long dmp_permit_id;
...
Permit
@Entity
@Table(name = "permit")
public class Permit {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;