2011-08-17 214 views
0

excesive querys我有以下实体:JPA映射实体

@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个来电数据库。有人知道为什么会发生这种情况,我怎么能避免这么多的电话?非常感谢。

+0

50个电话在做什么? – atrain

回答

0

你在该类中映射了很多关联。我希望所有的选择都在你使用时发生,因此初始化懒惰的引用。如果它不会造成问题,那就放手吧。否则请阅读Fetching Strategies以了解可以调整hibernate查询的不同方法。

0

我建议仔细看看数据库调用的发生时间以及查询的内容。

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

这将显示/记录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> 
0

是的,你的所有是正确的,问题是,@PostLoad方法引用相同的实体之间的关系,在其他单词,它称为estructurasOrganicas属性。这导致了数据库的递归提取。我第一次没有看到PostLoad方法,这是问题所在。非常感谢。