Java JPA-具有自定义左连接的规范
我有4个实体:Java JPA-具有自定义左连接的规范,java,oracle,hibernate,jpa,Java,Oracle,Hibernate,Jpa,我有4个实体:Parent、Alpha、Omega、Beta @Audited @Entity @Table(name = "parent") public class Parent extends AuditEntity { @Id @Column(nullable = false) @GeneratedValue .... private Long id; @OneToMany(mappedBy = "parent", fetch = FetchType
Parent、Alpha、Omega、Beta
@Audited @Entity @Table(name = "parent")
public class Parent extends AuditEntity {
@Id @Column(nullable = false)
@GeneratedValue ....
private Long id;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL,
orphanRemoval = true)
@JsonIgnore
private Set<Alpha> alphas;
}
/**
* Alpha connects Parent & Omega by containing their Ids mapping. It uses ParentAlphaId.java as ID class.
*/
@Audited @Entity @Table (name = "alpha")
@IdClass(ParentAlphaId.class)
public class Alpha extends AuditEntity {
@Id
@Column(name = "parent_id", nullable = false)
private Long parentId;
@Id
@Column(name = "omega_id", nullable = false)
private Long omegaId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
private Parent parent;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "omega_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
private Omega omega;
}
@Entity @Audited @Table(name = "omega"
public class Omega extends AuditEntity {
@Id
@GeneratedValue ....
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "beta", nullable = false)
private Beta beta;
}
@Entity @Audited @Table(name = "beta")
public class Beta extends AuditEntity {
@Id @Column
private long id;
@Column(nullable = false)
private Integer archived; // archived can be 0 or 1.
}
其目的是从父级、alpha和omega获取ID,在beta中存档的ID为0
对于beta为1的其他记录,它将报告为null
为此,我在父级存储库中编写了以下规范,即root
位于Parent
:
public static Specification<Parent> getParentWithActiveBeta() {
return (root, query, cb) -> {
Fetch<Object, Object> alpha = root.fetch("alpha", JoinType.LEFT);
Fetch<Object, Object> omega = alpha.fetch("omega", JoinType.LEFT);
Fetch<Object, Object> beta = omega.fetch("beta", JoinType.LEFT);
beta.on(cb.equal(beta.get("archived"), 0));
return null;
};
}
公共静态规范getParentWithActiveBeta(){
返回(根、查询、cb)->{
Fetch alpha=root.Fetch(“alpha”,JoinType.LEFT);
Fetch omega=alpha.Fetch(“omega”,JoinType.LEFT);
Fetch beta=omega.Fetch(“beta”,JoinType.LEFT);
beta.on(cb.equal(beta.get(“存档”),0));
返回null;
};
}
SQL查询似乎工作得很好,但当我运行规范时,我会得到归档为1的记录的测试版ID
我原以为它们会变成空的
我缺少什么?您不应该使用
fetch
而是join
,因为fetch
会导致JPQL/HQLjoin fetch
不支持谓词上的。您可以使用如下所示的存储库方法:
@Query("SELECT p.id, a.id, o.id, b.id, b.archived FROM Parent p JOIN p.alphas a JOIN a.omega o JOIN o.beta b ON b.archived = false")
public List<Tuple> findWhatever();
@Query(“选择p.id、a.id、o.id、b.id、b.archived FROM Parent p JOIN p.alphas a JOIN a.omega o JOIN o.beta b ON b.archived=false”)
公共列表findWhatever();
您不应该使用fetch
而是join
,因为fetch
会导致JPQL/HQLjoin fetch
不支持上的谓词。您可以使用如下所示的存储库方法:
@Query("SELECT p.id, a.id, o.id, b.id, b.archived FROM Parent p JOIN p.alphas a JOIN a.omega o JOIN o.beta b ON b.archived = false")
public List<Tuple> findWhatever();
@Query(“选择p.id、a.id、o.id、b.id、b.archived FROM Parent p JOIN p.alphas a JOIN a.omega o JOIN o.beta b ON b.archived=false”)
公共列表findWhatever();