Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何在使用Spring EntityManager Hibernate持久化大型集合时提高性能_Performance_Spring_Hibernate_Jdbc_Persistence.xml - Fatal编程技术网

Performance 如何在使用Spring EntityManager 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中的各种选项来加速插入并减少内存使用(应用程序写的和读的一样多) 编辑其他信

我正在使用Spring/Hibernate,使用
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;
}