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

时间:2015-04-08 13:14:23

标签: hibernate jpa querydsl

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

Proveedor

IdProveedor | RazonSocial

Empresa与

IdEmpresa | Nombre

ProveedorEmpresa

IdProveedor | IdEmpresa

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

PROVEEDOR

@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;
    }
}

我有这个方法返回所有Empresa及其Proveedor(因为是EAGER提取):

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

现在,我希望这个其他方法在没有Empresa的情况下返回所有Proveedor

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

我尝试在FetchProfile实体中添加Empresa

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

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

提前致谢。

1 个答案:

答案 0 :(得分:1)

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

你的课程看起来像这样

@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,您必须先获取hibernate会话,然后使用FetchProfile或使用建议的方法here