12

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

使用控制台中的 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>

我究竟做错了什么?

4

3 回答 3

6

别再和 JPAContainer 争了,它背后的抽象层太多了。

在此处输入图像描述

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

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

使用 CachingLocalEntityProvider

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

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

使用分页(PagedTable

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

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

在此处输入图像描述

使用 JPAContainer 过滤器

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

另请检查: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. 创建一个服务层(EJB、Spring 数据源,或者只是一个自定义帮助器类),在它后面隐藏 EntityManager 和 UI 代码中的其他 JPA 内容。
  2. 对于中小型表,只需将内容加载到内存中即可。简单且效率惊人,尤其是在 Viritin 附加组件中的ListContainer 等内存容器中表现良好。
  3. 对于内存使用可能成为问题的非常大的表,请使用 LazyList 帮助器通过服务层实现数据的延迟加载。查看我最近关于该主题的博客文章。
于 2015-01-23T13:49:01.383 回答