执行查询后,Hibernate需要很长时间才能返回对象

时间:2014-11-07 19:44:06

标签: java hibernate

我有一个查询返回单个类的大约1200个元素。我使用log4jdbc描述了查询执行,查询本身运行在70ms左右;但是我的dao方法(以return query.list()结尾)花了很长时间才将对象列表返回给我的服务(最多7s),好像问题与映射有某种关系。

这是我的班级:

@Entity
@Table(name = "unidad_funcional", uniqueConstraints = { @UniqueConstraint(columnNames = { "id_unidad_funcional", "id_subempresa" }) })
public class UnidadFuncional extends AbstractEntity {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;


    @Id
    @Column(name = "id_unidad_funcional_PK")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen_UF")
    @SequenceGenerator(name = "gen_UF", sequenceName = "SEQ_unidad_funcio_id_unidad_fu")
    private Integer idUnidadFuncionalPK;

    @Column(name = "id_unidad_funcional")
    private String idUnidadFuncional;

    @Column(name = "unidad_funcional")
    private String unidadFuncional;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_subempresa")
    private SubEmpresa subEmpresa;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_agrupacion_funcional")
    private AgrupacionFuncional agrupacionFuncional;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "unidadFuncional")
    private Set<Contrato> contratos = new HashSet<Contrato>();

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "up_unidad_funcional", joinColumns = { @JoinColumn(name = "id_unidad_planificacion") }, inverseJoinColumns = { @JoinColumn(name = "id_unidad_funcional") })
    private Set<UnidadPlanificacion> unidadesPlanificacion = new HashSet<UnidadPlanificacion>();

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "unidad_funcional_centro", joinColumns = { @JoinColumn(name = "id_unidad_funcional") }, inverseJoinColumns = { @JoinColumn(name = "id_centro") })
    private Set<Centro> centros = new HashSet<Centro>();

    (....)
}

这是执行的查询:

 select
        distinct unidadfunc0_.id_unidad_funcional_PK as id1_45_,
        unidadfunc0_.borrado as borrado45_,
        unidadfunc0_.fecha_alta as fecha3_45_,
        unidadfunc0_.propietario as propieta4_45_,
        unidadfunc0_.fecha_modificacion as fecha5_45_,
        unidadfunc0_.version as version45_,
        unidadfunc0_.id_agrupacion_funcional as id9_45_,
        unidadfunc0_.id_unidad_funcional as id7_45_,
        unidadfunc0_.id_subempresa as id10_45_,
        unidadfunc0_.unidad_funcional as unidad8_45_ 
    from
        unidad_funcional unidadfunc0_ 
    where
        unidadfunc0_.borrado = ? 
    order by
        lower(unidadfunc0_.unidad_funcional) asc

我知道我有几个关系,但是我检查了一下这些关系并没有得到 - 所以这不是问题所在。

我觉得1200个元素对于Hibernate来说并不是那么长,以便花很长时间来映射对象(特别是这么小的对象),所以任何关于问题所在的提示都会受到赞赏。

编辑:这是查询代码(使用queryDSL - 我也试过一个没有过滤的简单标准):

public List<UnidadFuncional> getUnidadesFuncionalesByFiltros(UnidadFuncionalFiltro filtro) {

        final JPAQuery query = new JPAQuery(getEntityManager());
        final JPAQuery subQuerySubEmpresas = new JPAQuery(getEntityManager());
        final QUnidadFuncional qu = QUnidadFuncional.unidadFuncional1;
        final QSubEmpresa qsub = QSubEmpresa.subEmpresa;

        query.from(qu);
        if(filtro.isIncluirDesactivados()) {
            disableFilterByDeleted();
        }
        if(StringUtils.isNotBlank(filtro.getIdCentro())){
            query.where(qu.subEmpresa().centros.any().idCentro.eq(filtro.getIdCentro()));
        }

        if(!filtro.getIdSubempresa().equals("")) {
            query.where(qu.subEmpresa().idSubempresa.eq(Integer.parseInt(filtro.getIdSubempresa())));
        }
        if(!filtro.getIdEmpresa().equals("")){
            subQuerySubEmpresas.from(qsub);
            subQuerySubEmpresas.where(qsub.empresa().idEmpresa.eq(Integer.parseInt(filtro.getIdEmpresa())));
            List<Integer> lista = subQuerySubEmpresas.listDistinct(qsub.idSubempresa);
            if (lista != null && lista.size() > 0) {
                query.where(qu.subEmpresa().idSubempresa.in(lista));
            }
        }
        query.orderBy(qu.unidadFuncional.toLowerCase().asc());
        return query.listDistinct(qu);
PD:顺便说一句,这只是一个例子,但这实际上发生在我的大部分实体中!

1 个答案:

答案 0 :(得分:0)

好吧,我会看3个地方。

1)仅仅因为查询完成执行并不意味着你已经完成了IO与数据库。如果这些记录很大或连接速度很慢,那么获取每条记录可能会导致速度问题。

2)你是否正在使用show_sql = true来确保在创建对象时没有运行很多子查询?

3)完全是在其他地方。当我在查询后在一个大循环中连接字符串时,我已经做了类似的事情。切换到将所有内容附加到StringBuilder可以节省大量成本。