我正在使用这个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>
我做错了什么?
答案 0 :(得分:6)
停止战斗JPAContainer,背后有太多的抽象层。
SQLContainer足够好,快速而稳定。我不是说SQLContainer是JPAContainer的替代品,但实际价格似乎太高了。从可用性的角度来看,响应性是一个非常重要的因素,因此最好不要在持久层上花费秒开始。
无论如何,如果您真的想继续使用JPAContainer,可以选择几个选项:
使用CachingLocalEntityProvider
经验法则:访问速度慢 - 使用缓存
如果应减少数据库往返次数, 应该使用CachingLocalEntityProvider。它保持着 实体和查询结果的本地缓存因此应该执行 如果数据库往返速度很慢,则比LocalEntityProvider快。 但是,它还需要比LocalEntityProvider更多的内存。
使用分页(PagedTable)
它会大大减少查询次数,因为页面是延迟加载的。
PagedTable是一个与行为相同的组件 Vaadin核心表,除了它有多个页面而不是 滚动显示更多条目。
使用JPAContainer过滤器
所有过滤都在数据库级别使用查询完成,而不是在容器中完成。 过滤实现透明地使用JPA 2.0 Criteria API。 由于过滤是在数据库级别完成的,因此使用Filterable API的自定义过滤器不起作用。
答案 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很方便但有问题。不仅仅是性能,还有架构问题。除非你依赖它非常漂亮的自动表单生成,否则就忘了它。
我的建议: