12

この 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>

私は何を間違っていますか?

4

3 に答える 3

6

JPAContainerとの戦いをやめてください。背後にある抽象化レイヤーが多すぎます。

ここに画像の説明を入力してください

SQLContainerは十分に優れており、高速で安定しています。SQLContainerがJPAContainerの代わりになると言っているわけではありませんが、実際の価格は高すぎるようです。使いやすさの観点から、応答性は非常に重要な要素であるため、永続性レイヤーに費やされる秒数から始めない方がよいでしょう。

とにかく、本当にJPAContainerを続行したい場合は、いくつかのオプションを利用できます。

CachingLocalEntityProviderを使用する

経験則:アクセスが遅い-キャッシュを使用する

データベースのラウンドトリップの数を減らす必要がある場合は、代わりにCachingLocalEntityProviderを使用する必要があります。エンティティとクエリ結果のローカルキャッシュを維持するため、データベースのラウンドトリップが遅い場合は、LocalEntityProviderよりも高速に実行する必要があります。ただし、LocalEntityProviderよりも多くのメモリが必要です。

ページングを使用する(PagedTable

ページが遅延ロードされるため、クエリの数が大幅に削減されます。

PagedTableは、Vaadinコアテーブルと同じように動作するコンポーネントですが、スクロールしてより多くのエントリを表示するのではなく、複数のページがある点が異なります。

ここに画像の説明を入力してください

JPAContainerフィルターを使用する

すべてのフィルタリングは、コンテナではなく、クエリを使用してデータベースレベルで実行されます。フィルタリングの実装では、JPA 2.0CriteriaAPIを透過的に使用します。フィルタリングはデータベースレベルで行われるため、FilterableAPIを使用するカスタムフィルターは機能しません。

また、JPAContainerの使用法とパフォーマンスに関する質問も確認してください。

于 2013-02-04T22:51:07.573 に答える
1

私の解決策

JPAContainerX で JPAContainer を拡張し、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);
于 2014-08-04T16:54:52.730 に答える
0

JPAContainer は便利ですが、問題があります。パフォーマンスだけでなく、アーキテクチャの問題も同様です。非常に優れた自動フォーム生成に依存しない限り、忘れてください。

私のおすすめ:

  1. UI コードから EntityManager やその他の JPA を非表示にするサービス レイヤー (EJB、Spring データ ソース、または単なるカスタム ヘルパー クラス) を作成します。
  2. 小規模から中規模のテーブルの場合は、それらをメモリにロードするだけです。シンプルで驚くほど効率的です。特に、Viritin アドオンの ListContainer のようなパフォーマンスの高いメモリ コンテナーを使用すると効果的です。
  3. メモリ使用量が問題になる可能性がある非常に大きなテーブルの場合、LazyList ヘルパーを使用して、サービス レイヤーを介したデータの遅延読み込みを実装します。この件に関する私の最近のブログエントリをチェックしてください。
于 2015-01-23T13:49:01.383 に答える