2012-12-03 24 views
12

Tôi đang làm việc JPAContainer + Hibernate này và mất nhiều thời gian để tải. Ví dụ trang với SQLContainer tải 60ms và cùng một trang với JPA Container tải 1,30s.Vaadin JpaContainer

Với JPAContainer trong bảng điều khiển, tôi thấy nhiều truy vấn SQL - cho mỗi truy vấn thực thể; Entity Person không có liên kết đến các bảng khác;

Mã với jpacontainer:

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

Mã với 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 My file:

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

Tôi đang làm gì sai?

Trả lời

6

Dừng chiến đấu JPAContainer, có quá nhiều lớp trừu tượng phía sau nó.

enter image description here

SQLContainer là đủ tốt, nhanh chóng và ổn định. Tôi không nói SQLContainer là một sự thay thế cho JPAContainer, nhưng giá thực tế có vẻ quá cao. Từ góc độ khả năng sử dụng, đáp ứng là một yếu tố rất quan trọng, vì vậy tốt hơn là không bắt đầu với giây, dành cho lớp kiên trì.

Dù sao, có một số tùy chọn có sẵn nếu bạn thực sự muốn tiếp tục với JPAContainer:

Sử dụng CachingLocalEntityProvider

Rule of thumb: Truy cập chậm - sử dụng bộ nhớ cache

Nếu số lượng cơ sở dữ liệu khứ hồi nên được giảm, CachingLocalEntityProvider nên được sử dụng thay thế. Nó duy trì bộ nhớ cache cục bộ và các kết quả truy vấn và do đó sẽ thực hiện nhanh hơn LocalEntityProvider nếu cơ sở dữ liệu vòng chuyến đi chậm. Tuy nhiên, nó cũng đòi hỏi nhiều bộ nhớ hơn LocalEntityProvider.

Sử dụng phân trang (PagedTable)

Nó sẽ làm giảm đáng kể số lượng các truy vấn, vì các trang là lười biếng nạp.

PagedTable là một thành phần mà ứng xử trong vấn đề tương tự như bảng lõi Vaadin, ngoại trừ việc nó có nhiều trang thay vì cuộn để hiển thị nhiều mục.

enter image description here

Sử dụng JPAContainer lọc

Tất cả lọc được thực hiện ở cấp cơ sở dữ liệu với các truy vấn, không phải trong container. Triển khai lọc sử dụng API tiêu chí JPA 2.0 một cách minh bạch. Khi việc lọc được thực hiện ở cấp cơ sở dữ liệu, các bộ lọc tùy chỉnh sử dụng API có thể lọc không hoạt động.

cũng Vui lòng kiểm tra: JPAContainer Usage and Performance questions

+0

Lưu ý rằng thùng chứa JPA của Vaadin hiện có * giấy phép miễn phí *. –

1

giải pháp của tôi

mở rộng JPAContainer trong JPAContainerX, ghi đè getItemIds

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

sau đó

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); 
0

JPAContainer là tiện dụng nhưng có vấn đề của nó. Không chỉ hiệu suất, mà còn là vấn đề về kiến ​​trúc. Trừ khi bạn phụ thuộc vào thế hệ hình dạng tự động khá đẹp của nó, chỉ cần quên nó đi.

Đề nghị của tôi:

  1. Tạo một lớp dịch vụ (EJB, nguồn dữ liệu mùa xuân, hay chỉ là một lớp tùy chỉnh helper) sau đó bạn ẩn EntityManager và các công cụ khác JPA từ mã UI của bạn.
  2. Đối với các bảng có kích thước nhỏ đến trung bình, chỉ cần tải nội dung vào bộ nhớ. Đơn giản và đáng ngạc nhiên hiệu quả, đặc biệt là với một hoạt động tốt trong bộ nhớ Container như ListContainer từ the Viritin add-on.
  3. Đối với các bảng thực sự lớn nơi sử dụng bộ nhớ có thể trở thành vấn đề, hãy sử dụng trình trợ giúp LazyList để triển khai tải dữ liệu chậm qua lớp dịch vụ của bạn. Hãy xem chủ đề gần đây của tôi blog entry about.
Các vấn đề liên quan