【问题标题】:Vaadin JpaContainerVaadin JpaContainer
【发布时间】:2012-11-20 18:55:27
【问题描述】:

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

使用控制台中的 JPAContainer,我看到许多 SQL 查询 - 对于每个实体 - 查询;实体 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>

我做错了什么?

【问题讨论】:

    标签: hibernate vaadin


    【解决方案1】:

    停止与 JPAContainer 争斗,它背后的抽象层太多了。

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

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

    使用 CachingLocalEntityProvider

    经验法则:访问缓慢——使用缓存

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

    使用分页 (PagedTable)

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

    PagedTable 是一个与 Vaadin 核心表,除了它有多个页面而不是 滚动显示更多条目。

    使用 JPAContainer 过滤器

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

    另请查看:JPAContainer Usage and Performance questions

    【讨论】:

    • 请注意,Vaadin 的 JPA 容器目前有一个免费许可证
    【解决方案2】:

    我的解决方案

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

    【讨论】:

      【解决方案3】:

      JPAContainer 很方便,但也有问题。不仅是性能,还有架构问题。除非你依赖它相当不错的自动表单生成,否则别管它了。

      我的建议:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多