0

我有以下实体:

    @Name("estructuraOrganica")
    @Entity
    @Table(name = "srht_estructuras_organicas")
    public class EstructuraOrganica extends EntidadBasica implements Auditable,
    Desplegable<EstructuraOrganica> {

private static final long serialVersionUID = 1L;

@NotNull
@Length(max = 50)
@Column(name = "codigo", nullable = false, length = 50)
private String codigo;

@Length(max = 300)
@Column(name = "nombre", nullable = true, length = 160)
private String nombre;

@Column(name = "institucion_id")
private Long institucionId;

@NotNull
@Length(max = 1)
@Column(name = "es_uarh", nullable = false, length = 1)
private String esUARH;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "catalogo_jerarquia_proceso_unidad_id", nullable = false)
@Fetch(FetchMode.SELECT)
private Catalogo catalogoJerarquiaProcesoUnidad;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "estatuto_id", nullable = false)
private Estatuto estatuto;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "estructura_organica_padre_id", nullable = true)
private EstructuraOrganica estructuraOrganicaPadre;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "padre_auxiliar_estructura_id", nullable = true)
private EstructuraOrganica estructuraOrganicaJerarquia;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "estado_id", nullable = false)
@Fetch(FetchMode.SELECT)
private Estado estado;

@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY,                             mappedBy                    =                           "estructuraOrganicaPadre")
@OrderBy(value = "codigo")
private List<EstructuraOrganica> estructurasOrganicas;

@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "estructuraOrganica")
private List<OrganigramaPosicion> organigramasPosiciones;

@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "estructuraOrganica")
@Where(clause = "estado_id=1")
private List<OrganigramaPosicion> organigramasPosicionesActivas;

@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "estructuraOrganicaPadre")
@OrderBy(value = "codigo")
@Where(clause = "estado_id=1")
private List<EstructuraOrganica> estructurasOrganicasActivas;

@Column(name = "estado_plan_vacaciones")
private Integer estadoPlanVacaciones;

@Column(name = "tipo")
private Integer tipo;

@Column(name = "puesto_jefe_inmediato")
private Long puestoJefeInmediato;   

@Length(max = 10)
@Column(name = "codigo_mef", nullable = true, length = 10)
private String codigoMef;

@Transient
private Boolean puedeEliminarse;

@Transient
private Boolean uarh;

@Transient
private Boolean puedeGrabarse;

@Transient
private RegimenDePersonal regimenDePersonal;

@Column(name="institucion_desconcentrada_id")
private Long institucionDesconcentradaId;

... Getters and Setters omitted...

   }

现在查找该实体的某个实例的 JPQL 查询如下:

   SELECT o FROM EstructuraOrganica o WHERE o.estatuto.institucion.id=:institucionId and        o.estructuraOrganicaPadre is null AND o.estado.id=1 ORDER BY o.codigo ASC")

然而,问题是这个简单的查询会产生过多的数据库调用......基本上是在做选择。用于执行相同操作的本机 sql 可能是:

    SELECT * from sch_senres.srht_estructuras_organicas,
          sch_senres.srht_estatutos,
          sch_senres.srht_instituciones,
          sch_senres.srht_estados
    WHERE sch_senres.srht_estructuras_organicas.estatuto_id=sch_senres.srht_estatutos.id
    AND   sch_senres.srht_estructuras_organicas.estado_id=sch_senres.srht_estados.id
    AND   sch_senres.srht_estatutos.institucion_id=sch_senres.srht_instituciones.id
    AND   sch_senres.srht_instituciones.id=91122
    AND   sch_senres.srht_estados.id=1
    AND   sch_senres.srht_estructuras_organicas.estructura_organica_padre_id IS NULL
    ORDER BY sch_senres.srht_estructuras_organicas.codigo

所以想法是像这样创建一个 NativeQuery:

    Query query=entityManager.createNativeQuery("SELECT * from  sch_senres.srht_estructuras_organicas,"+                                                    "sch_senres.srht_estatutos,sch_senres.srht_instituciones,"+
                                                "sch_senres.srht_estados "+
                                                "WHERE sch_senres.srht_estructuras_organicas.estatuto_id=sch_senres.srht_estatutos.id "+
                                                "AND   sch_senres.srht_estructuras_organicas.estado_id=sch_senres.srht_estados.id "+
                                                "AND   sch_senres.srht_estatutos.institucion_id=sch_senres.srht_instituciones.id "+
                                                "AND   sch_senres.srht_instituciones.id= :institucionId "+
                                                "AND   sch_senres.srht_estados.id=1 "+
                                                "AND   sch_senres.srht_estructuras_organicas.estructura_organica_padre_id IS NULL "+
                                                "ORDER BY sch_senres.srht_estructuras_organicas.codigo", EstructuraOrganica.class);
    query.setParameter("institucionId", institucionId);

但是我没有得到任何结果……休眠继续对数据库进行 50 次调用。有谁知道为什么会发生这种情况,我怎么能避免这么多电话?非常感谢。

4

3 回答 3

0

您在该类中映射了很多关联。我希望所有选择都在您使用并因此初始化惰性引用时发生。如果它没有引起问题,那就让它发生吧。否则,请阅读Fetching Strategies以了解调整休眠查询的不同方法。

于 2011-08-18T01:29:33.463 回答
0

是的,你们都说对了,问题是@PostLoad 方法引用的是同一个实体的关系,换句话说,它是在调用 estructurasOrganicas 属性。这导致从数据库中递归获取。我第一次没有看到 PostLoad 方法,这就是问题所在。非常感谢。

于 2011-08-18T14:26:08.493 回答
0

我建议仔细查看数据库调用的确切时间,以及它们到底查询了什​​么。

如果您还没有这样做,我建议您通过休眠激活 SQL 语句的日志记录:
您必须将日志记录设置为:
org.hibernate.type到 TRACE 级别。
org.hibernate.SQL到调试级别。

这将显示/记录 hibernate 用于持久性的所有 SQL 语句和参数。

在 Log4J 中,上面的登录将被配置为这样......

<category name="org.hibernate.type">
  <priority value="TRACE"/>
  <appender-ref ref="[..whatever appender you want..]"/>
</category>
<category name="org.hibernate.SQL">
  <priority value="DEBUG"/>
  <appender-ref ref="[..whatever appender you want..]"/>
</category>
于 2011-08-18T06:54:26.470 回答