Подтвердить что ты не робот

Ваадин JpaContainer

Я работаю над этим JPAContainer + Hibernate, и загрузка занимает много времени. Например, страница с загрузкой SQLContainer 60 мс и той же страницей с загрузкой контейнера JPA 1.30 с.

С JPAContainer в консоли я вижу много SQL-запросов - для каждого объекта - запроса; Entity Person не имеет ссылок на другие таблицы;

Код с jpacontainer:

JPAContainer<Person> container = JPAContainerFactory.make(Person.class,
            "persistence-unit");
table.setContainerDataSource(container);

Код с SQLContainer:

JDBCConnectionPool pool = null;
    try {
        pool = new SimpleJDBCConnectionPool("org.postgresql.Driver",
                "jdbc:postgresql://127.0.0.1:5432/postgres", "postgres",
                "pwd");
    } catch (SQLException e) {
        e.printStackTrace();
    }
    TableQuery tq = new TableQuery("Person", pool);
    SQLContainer sqlContainer = null;
    try {
        sqlContainer = new SQLContainer(tq);
    } catch (SQLException e) {
        e.printStackTrace();
    }
table.setContainerDataSource(sqlContainer);

Мой файл persistence.xml:

<persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL">

  <jta-data-source>java:jboss/datasources/mfc-frontendDS</jta-data-source>

  <properties>
     <!-- Properties for Hibernate -->
    <property name="hibernate.archive.autodetection" value="class"/>
    <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
    <property name="hibernate.show_sql" value="true"/>
    <property name="hibernate.format_sql" value="true"/>
    <property name="hibernate.use_sql_comments" value="true"/>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> 
  </properties>

Что я делаю неправильно?

4b9b3361

Ответ 1

Прекратите борьбу с JPAContainer, за ним слишком много слоев абстракции.

enter image description here

SQLContainer достаточно хорош, быстр и стабилен. Я не говорю, что SQLContainer является заменой для JPAContainer, но фактическая цена кажется слишком высокой. С точки зрения удобства использования отзывчивость - очень важный фактор, поэтому лучше не начинать с секунд, потраченных на уровень сохранения.

В любом случае, есть несколько вариантов, если вы действительно хотите продолжить работу с JPAContainer:

Использовать CachingLocalEntityProvider

Правило большого пальца: медленный доступ - используйте кеш

Если число обращений к базам данных должно быть уменьшено, Вместо этого следует использовать CachingLocalEntityProvider. Он поддерживает локальный кэш объектов и результаты запроса и, следовательно, должны выполнять быстрее, чем LocalEntityProvider, если транзакции базы данных медленны. Однако для этого также требуется больше памяти, чем LocalEntityProvider.

Использовать пейджинг (PagedTable)

Это значительно уменьшит количество запросов, так как страницы будут загружены в лени.

PagedTable - это компонент, который ведет себя в том же вопросе, что и Vaadin core Table, за исключением того, что у него есть несколько страниц вместо прокрутка, чтобы показать больше записей.

enter image description here

Использовать фильтры JPAContainer

Вся фильтрация выполняется на уровне базы данных с запросами, а не в контейнере. Реализация фильтрации использует прозрачный API-интерфейс JPA 2.0. Поскольку фильтрация выполняется на уровне базы данных, пользовательские фильтры, которые используют Filterable API, не работают.

Также проверьте: Вопросы использования и производительности JPAContainer

Ответ 2

мое решение

расширяет JPACконтейнер в JPAContainerX, переопределяет getItemIds

@Override
public List<?> getItemIds(int startIndex, int numberOfItems) {
    return doGetEntityProvider().getAllEntityIdentifiers(this,getAppliedFiltersAsConjunction(), getSortByList() ).subList(startIndex, startIndex+numberOfItems);;
}

затем

JPAContainerX<T> container = new JPAContainerX<T>(c);

    EntityManager entityManager = JPAContainerFactory.createEntityManagerForPersistenceUnit( IntrastudyUI.PERSISTENCE_UNIT );

    CachingMutableLocalEntityProvider<T> entityProvider = new CachingMutableLocalEntityProvider<T>( c ,  entityManager);

    container.setEntityProvider(entityProvider);

Ответ 3

JPAContainer удобен, но имеет свои проблемы. Не просто производительность, но и архитектурные проблемы. Если вы не зависите от его довольно приятного автоматического создания формы, просто забудьте об этом.

Мое предложение:

  • Создайте сервисный уровень (EJB, Spring Источник данных или только пользовательский вспомогательный класс), за которым вы скрываете EntityManager и другие элементы JPA от вашего кода пользовательского интерфейса.
  • Для таблиц малого и среднего размера просто загружайте материал в память. Простой и удивительно эффективный, особенно с хорошо выполняющимся в памяти контейнером, как ListContainer от надстройка Viritin.
  • Для действительно больших таблиц, где использование памяти может стать проблемой, используйте помощник LazyList для реализации ленивой загрузки данных через ваш сервисный уровень. Ознакомьтесь с моей недавней записью в блоге о теме.