在@ManyToMany Hibernate 关系的运行时更改获取类型

Change fetch type in runtime of @ManyToMany Hibernate relationship

我正在使用 Hibernate/JPA 和 QueryDSL。我的数据库中有这个表:

校对人

IdProveedor | RazonSocial

Empresa

IdEmpresa | Nombre

ProveedorEmpresa

IdProveedor | IdEmpresa

ProveedorEmpresa之间存在多对多关系。这是我的 JPA 映射:

检验员

@Entity
public class Proveedor {

    private String idProveedor;
    private String razonSocial;
    @IgnoredField
    private List<Empresa> empresas;

    @Id
    @Column(name = "IdProveedor")
    public String getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(String idEmpresa) {
        this.idProveedor = idEmpresa;
    }

    @Basic
    @Column(name = "RazonSocial")
    public String getRazonSocial() {
        return razonSocial;
    }

    public void setRazonSocial(String razonSocial) {
        this.razonSocial = razonSocial;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "ProveedorEmpresa", joinColumns = {
            @JoinColumn(name = "IdProveedor", nullable = false, updatable = false)},
            inverseJoinColumns = {
                    @JoinColumn(name = "IdEmpresa", nullable = false, updatable = false)
            })
    public List<Empresa> getEmpresas() {
        return empresas;
    }

    public void setEmpresas(List<Empresa> empresas) {
        this.empresas = empresas;
    }

}

EMPRESA

@Entity
public class Empresa {

    private String idEmpresa;
    private String razonSocial;
    private String abreviatura;
    private List<Proveedor> proveedores;

    @Id
    @Column(name = "IdEmpresa")
    public String getIdEmpresa() {
        return idEmpresa;
    }

    public void setIdEmpresa(String idEmpresa) {
        this.idEmpresa = idEmpresa;
    }

    @Basic
    @Column(name = "RazonSocial")
    public String getRazonSocial() {
        return razonSocial;
    }

    public void setRazonSocial(String razonSocial) {
        this.razonSocial = razonSocial;
    }

    @Basic
    @Column(name = "Abreviatura")
    public String getAbreviatura() {
        return abreviatura;
    }

    public void setAbreviatura(String abreviatura) {
        this.abreviatura = abreviatura;
    }

    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "empresas")
    public List<Proveedor> getProveedores() {
        return proveedores;
    }

    public void setProveedores(List<Proveedor> proveedores) {
        this.proveedores = proveedores;
    }
}

我有这个方法 returns 所有 Empresa 和他们的 Proveedor (因为是 EAGER fetch):

public List<Empresa> getEmpresasWithProveedores() { 
        JPAQuery query = new JPAQuery();
        query.from(qEmpresa);
        return query.list(qEmpresa);
}

现在,我想要另一种方法 returns 所有 Empresa 没有他们的 Proveedor:

public List<Empresa> getEmpresasWithoutProveedores() { 
        // Set the fetch type to LAZY
        JPAQuery query = new JPAQuery();
        query.from(qEmpresa);
        return query.list(qEmpresa);
}

我尝试在 Empresa 实体中添加一个 FetchProfile

@Entity
@FetchProfile(name = "WITH_PROVEEDORES", fetchOverrides = {
        @FetchProfile.FetchOverride(entity = Empresa.class, association = "proveedores", mode = FetchMode.JOIN)})
public class Empresa { . . . }

和 enable/disable 它在每个方法之前。但它不起作用,它具有相同的行为。实际上,我不明白 FetchProfile 是如何工作的以及我必须如何配置它才能获得我想要的行为。

提前致谢。

假设您使用的是 JPA 2.1,您需要使用与 FetchProfile 等效的 JPA 来执行相同的操作。

你的 class 看起来像这样

@Entity
@NamedEntityGraph(
        name = "WITH_PROVEEDORES",
                attributeNodes = {
    @NamedAttributeNode("proveedores")
}
)
public class Empresa {
.....

您可以运行这样查询,

  private static void queryWithProveedors() {
    EntityManager entityManager =   Persistence.createEntityManagerFactory("tutorialPU").
            createEntityManager();
    QEmpresa qEmpresa = QEmpresa.empresa;
    JPAQuery query = new JPAQuery (entityManager); 
    EntityGraph graph = entityManager.getEntityGraph("WITH_PROVEEDORES");
    query.from(qEmpresa).setHint("javax.persistence.fetchgraph", graph);
    query.list(qEmpresa);
    }

如果您不使用 JPA 2.1,要么必须获取休眠会话然后使用 FetchProfile,要么使用建议的方法 here