有两个实体,它们的名称分别为A和B。A和B没有映射,但是实体B具有名称为applicationId的属性,该属性也存在于实体A中。 / p>
@Entity
@Table(name = "b")
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
@Column(name = "id", columnDefinition = "uuid")
private UUID id;
@Column(name = "application_id")
private String applicationId;
@Column(name = "notification_name")
private bType type;
@Column(name = "is_mail_sent")
private boolean isMailSent = false;
@Column(name = "is_report_generated")
private boolean isReportGenerated = false;
}
@Entity
@Table(name = "a")
public class A extends implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "application_id", unique = true)
private String applicationId;
@Column(name = "ref_no", unique = true)
private String refNo;
}
public class BSpecification implements Specification<B> {
private final B criteria;
private transient List<Predicate> predicateList = new ArrayList<>();
public NotificationSpecification(B partyCriteria) {
this.criteria = partyCriteria;
}
@Override
public Predicate toPredicate(Root<B> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
if (StringUtils.hasText(this.criteria.getApplicationId()))
this.predicateList.add(cb.like(root.get("applicationId"), "%" + criteria.getApplicationId() + "%"));
if (!StringUtils.isEmpty(this.criteria.getType()))
this.predicateList.add(cb.equal(root.get("type"), criteria.getType()));
if (StringUtils.hasText(this.criteria.getToEmail()))
this.predicateList.add(cb.like(root.get("toEmail"), "%" + criteria.getToEmail() + "%"));
if (this.criteria.getCreatedDate() != null) {
this.predicateList.add(cb.between(root.get("createdDate"), DateUtil.getStartOrEndOfDay(criteria.getCreatedDate(), true),
DateUtil.getStartOrEndOfDay(criteria.getCreatedDate(), false)));
}
this.predicateList.add(cb.equal(root.get("isReportGenerated"), true));
return criteriaQuery.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])))
.getRestriction();
}
}
如果用户希望通过A中的refNo搜索B,则实体A具有refNo作为实体B中不存在的另一个属性,这可以通过用本机查询编写的Join Query来实现。
select nft from b as nft left join a app on app.application_id=nft.application_id
where app.ref_no='test1';
但是想通过JPA规范Criteria Builder来实现这一点,我在LEFT Join上发现了很少的示例,这些示例仅适用于已映射的实体,但找不到适用于不再映射的实体。