Performance 如何在使用Spring EntityManager Hibernate持久化大型集合时提高性能
我正在使用Spring/Hibernate,使用Performance 如何在使用Spring EntityManager Hibernate持久化大型集合时提高性能,performance,spring,hibernate,jdbc,persistence.xml,Performance,Spring,Hibernate,Jdbc,Persistence.xml,我正在使用Spring/Hibernate,使用org.springframework.orm.JPA.LocalContainerEntityManagerFactoryBean完成JPA方式,并使用SpringXML、persistence.xml和JPA2注释进行配置 从功能上讲,它是好的,并且能够正确地坚持。但是,我需要尽快存储实体a,该实体a具有一个具有大量B集合的双向单域 我使用persistence.xml中的各种选项来加速插入并减少内存使用(应用程序写的和读的一样多) 编辑其他信
org.springframework.orm.JPA.LocalContainerEntityManagerFactoryBean
完成JPA方式,并使用SpringXML、persistence.xml和JPA2注释进行配置
从功能上讲,它是好的,并且能够正确地坚持。但是,我需要尽快存储实体a,该实体a具有一个具有大量B集合的双向单域
我使用persistence.xml中的各种选项来加速插入并减少内存使用(应用程序写的和读的一样多)
编辑其他信息:
每个实体都有一个生成的id,如下所示:
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO, generator="SEQUENCE_GENERATOR")
@SequenceGenerator(name="SEQUENCE_GENERATOR", sequenceName="MY_SEQUENCE", allocationSize=50)
private Long id;
它与Oracle序列有关
CREATE SEQUENCE MY_SEQUENCE MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 50 NOCYCLE NOCACHE NOORDER;
当我在showsql打开的情况下运行代码时,我可以看到许多insert语句花费了相当长的时间
我读到需要调用entityManager.flush();entityManager.clear()代码>每插入50行
这是否意味着我需要将持久化分解为
entityManager.persist(instanceOfA);
instanceOfA.addB(instanceOfB);
entityManager.persist(instanceofB);
每50次调用persist()
添加刷新清除
有没有更干净的方法?(我的实际对象层次结构有大约7层关系,如A和B)
我曾考虑将JDBC用于插入,但我讨厌编写行映射器:)
我听说过org.hibernate.StatelessSession
,但是没有一种方法可以从JPA实体管理器中获得它,而不必在某个时候强制转换到SessionFactory——同样也不是很干净
提前谢谢 我在我的一个项目中遇到了同样的问题。我使用Hibernate和MySQL后端,带有identity
ID生成器。问题是,Hibernate需要为保存的每个实体点击数据库一次,以实际获取其ID。我切换到increment
生成器,看到了即时的好处(所有插入都成批处理)
增量
生成器在内存中生成ID,不需要访问数据库。我猜序列
生成器也需要访问数据库,因为它是在数据库中定义的。使用increment
的缺点是,Hibernate应该具有对数据库的独占插入访问权限,并且在集群设置中可能会失败
我使用的另一个技巧是将rewriteBatchedStatements=true
附加到JDBC URL。这是MySQL特有的,但我认为Oracle可能也有类似的指令
“每n次插入后调用flush”技巧也很有效。下面是一个示例代码(使用google guava类):
public List saveInBatches(final Iterable使用纯JDBC进行大容量/大容量插入。不要使用任何ORM框架。-为每个表插入创建一次PreparedStatement,并反复使用它们。2)使其成为多线程应用程序。我这里有一个类似的问题,必须插入数百个元素,这似乎是最好的方法,与处理内存中的许多项不同,只需在普通查询中插入必要的关系。
CREATE SEQUENCE MY_SEQUENCE MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 50 NOCYCLE NOCACHE NOORDER;
entityManager.persist(instanceOfA);
instanceOfA.addB(instanceOfB);
entityManager.persist(instanceofB);
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column(name = "id", nullable = false)
private long id;
public List<T> saveInBatches(final Iterable<? extends T> entities, final int batchSize) {
return ImmutableList.copyOf(
Iterables.concat(
Iterables.transform(
Iterables.partition(entities, batchSize),
new Function<List<? extends T>, Iterable<? extends T>>() {
@Override
public Iterable<? extends T> apply(final List<? extends T> input) {
List<T> saved = save(input); flush(); return saved;
}})));
}
public List<T> save(Iterable<? extends T> entities) {
List<T> result = new ArrayList<T>();
for (T entity : entities) {
entityManager.persist(entity);
result.add(entity);
}
return result;
}