Vaadin JpaContainer

时间:2012-12-03 10:11:11

标签: hibernate vaadin

我正在使用这个JPAContainer + Hibernate,加载需要很长时间。例如,SQLContainer加载60ms的页面和JPA Container加载1.30s的相同页面。

在控制台中使用JPAContainer,我看到许多SQL查询 - 对于每个实体 - 查询;实体人没有指向其他表的链接;

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

我做错了什么?

3 个答案:

答案 0 :(得分:6)

停止战斗JPAContainer,背后有太多的抽象层。

enter image description here

SQLContainer足够好,快速而稳定。我不是说SQLContainer是JPAContainer的替代品,但实际价格似乎太高了。从可用性的角度来看,响应性是一个非常重要的因素,因此最好不要在持久层上花费开始。

无论如何,如果您真的想继续使用JPAContainer,可以选择几个选项:

使用CachingLocalEntityProvider

经验法则:访问速度慢 - 使用缓存

  

如果应减少数据库往返次数,   应该使用CachingLocalEntityProvider。它保持着   实体和查询结果的本地缓存因此应该执行   如果数据库往返速度很慢,则比LocalEntityProvider快。   但是,它还需要比LocalEntityProvider更多的内存。

使用分页(PagedTable

它会大大减少查询次数,因为页面是延迟加载的。

  

PagedTable是一个与行为相同的组件   Vaadin核心表,除了它有多个页面而不是   滚动显示更多条目。

enter image description here

使用JPAContainer过滤器

  

所有过滤都在数据库级别使用查询完成,而不是在容器中完成。   过滤实现透明地使用JPA 2.0 Criteria API。   由于过滤是在数据库级别完成的,因此使用Filterable API的自定义过滤器不起作用。

请同时查看:JPAContainer Usage and Performance questions

答案 1 :(得分: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);

答案 2 :(得分:0)

JPAContainer很方便但有问题。不仅仅是性能,还有架构问题。除非你依赖它非常漂亮的自动表单生成,否则就忘了它。

我的建议:

  1. 创建一个服务层(EJB,Spring数据源,或者只是一个自定义帮助程序类),在其后面隐藏UI代码中的EntityManager和其他JPA内容。
  2. 对于中小型表,只需将内容加载到内存中即可。简单且令人惊讶的高效,特别是在内存中表现良好的容器,如the Viritin add-on中的ListContainer。
  3. 对于可能会出现内存使用问题的超大型表,请使用LazyList帮助程序通过服务层实现延迟加载数据。查看我最近的blog entry about主题。