2014-11-07 3 views
2

У меня есть запрос, который возвращает около 1200 элементов одного класса. Я профилировал выполнение запроса, используя log4jdbc, и сам запрос работает примерно в 70 мс; однако мой метод dao (который заканчивается с возвратом query.list()) занимает очень много времени, чтобы вернуть список объектов моей службе (до 7 секунд), как будто проблема была каким-то образом связана с отображением.Спящий режим слишком длинный для возврата объектов после выполнения запроса

Это мой класс:

@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 не так много, чтобы отобразить объекты (особенно с таким маленьким объектом), поэтому любые подсказки о том, где могла бы быть проблема, были бы оценены.

EDIT: Вот код запроса (с использованием 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: Кстати, это всего лишь пример, но это на самом деле происходит iwth большинство моих сущностей!

+0

Я ничего не вижу в этом коде, который должен занять так много времени. Проблема должна быть где-то в другом месте. Можете ли вы показать код, в котором выполняется запрос? –

+0

Я отредактировал свое оригинальное сообщение –

+0

Вы исправить эту проблему? – sakthi

ответ

0

Хорошо, я бы посмотрел 3 места.

1) Только потому, что выполненный запрос завершен, не означает, что вы закончили с IO с базой данных. Если эти записи огромны или ваше соединение происходит медленно, выборка каждой записи может вызвать проблемы с производительностью.

2) Используете show_sql = true, чтобы убедиться, что многие подзапросы не выполняются при создании объектов?

3) Это где-то еще полностью. Я сделал что-то подобное, когда я конкатенировал строки в большом цикле после запроса. Переход на добавление всего к StringBuilder привел к огромной экономии.

+0

log4jJDBC перехватывает соединение JDBC и время выполнения журналов после возврата строк, поэтому я бы сказал, что эта мера правильная. Мой код обслуживания просто вызывает метод DAO, который я только что разместил в исходном сообщении –

+0

извините, забыли сказать - я действительно использую show_sql = true и никаких дальнейших запросов не выполняется. –

+0

Вы пытались удалить orderby? или замените listDistinct на список? – osoblanco

Смежные вопросы