2011-08-17 209 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方法,這是問題所在。非常感謝。