我有一个查询返回单个类的大约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:顺便说一句,这只是一个例子,但这实际上发生在我的大部分实体中!
答案 0 :(得分:0)
好吧,我会看3个地方。
1)仅仅因为查询完成执行并不意味着你已经完成了IO与数据库。如果这些记录很大或连接速度很慢,那么获取每条记录可能会导致速度问题。
2)你是否正在使用show_sql = true来确保在创建对象时没有运行很多子查询?
3)完全是在其他地方。当我在查询后在一个大循环中连接字符串时,我已经做了类似的事情。切换到将所有内容附加到StringBuilder可以节省大量成本。