当前位置: 首页 > 面试题库 >

如何保留大量实体(JPA)

田修为
2023-03-14
问题内容

我需要处理一个CSV文件,并且对于每个记录(行)都保留一个实体。现在,我这样做:

while ((line = reader.readNext()) != null) {
    Entity entity = createEntityObject(line);
    entityManager.save(entity);
    i++;
}

save(Entity)方法基本上只是一个EntityManager.merge()调用。CSV文件中大约有20,000个实体(行)。这是一种有效的方法吗?似乎很慢。使用会更好EntityManager.persist()吗?这个解决方案有任何缺陷吗?

编辑

这是一个漫长的过程(超过400秒)和我都尝试的解决方案,与persistmerge。两者花费的时间大致相同(459s与443s)。问题是,像这样一个接一个地保存实体是否最佳。据我所知,Hibernate(这是我的JPA提供程序)确实实现了某些缓存/刷新功能,因此我不必为此担心。


问题答案:

JPA API并未为您提供最佳选择。根据您要执行此操作的速度,您将不得不寻找特定于ORM的选项-在您的情况下为休眠状态。

检查事项:

  1. 检查您是否正在使用单笔交易(是的,显然您对此有把握)
  2. 检查您的JPA提供程序(Hibernate)是否正在使用JDBC批处理API(请参阅:hibernate.jdbc.batch_size)
  3. 检查是否可以绕过获取生成的密钥(取决于db / jdbc驱动程序,您从中获得多少好处-请参阅:hibernate.jdbc.use_getGeneratedKeys)
  4. 检查您是否可以绕过级联逻辑(这样做只能带来最小的性能收益)

因此,在Ebean ORM中,这将是:

    EbeanServer server = Ebean.getServer(null);

    Transaction transaction = server.beginTransaction();
    try {
        // Use JDBC batch API with a batch size of 100
        transaction.setBatchSize(100);
        // Don't bother getting generated keys
        transaction.setBatchGetGeneratedKeys(false);
        // Skip cascading persist 
        transaction.setPersistCascade(false);

        // persist your beans ...
        Iterator<YourEntity> it = null; // obviously should not be null 
        while (it.hasNext()) {
            YourEntity yourEntity = it.next();
            server.save(yourEntity);
        }

        transaction.commit();
    } finally {
        transaction.end();
    }

哦,如果您通过原始JDBC执行此操作,则会跳过ORM开销(减少了对象创建/垃圾收集等操作),因此我不会忽略该选项。

因此,是的,这不能回答您的问题,但可以帮助您搜索更多针对ORM的特定批量插入调整。



 类似资料:
  • 问题内容: 我在Web应用程序中使用了JPA,但我想不出如何持久化彼此相关的两个新实体。这里是一个例子: 这是两个实体 该 消费者 有一个 ID 和其他一些价值观。该 ProfilePicture 使用 消费者 的 ID ,因为它是自己的主键和外键。(由于没有使用者,ProfilePicture将不存在,并且并非每个使用者都具有ProfilePicture) 我使用NetBeans生成实体类和会话

  • 我正在从经典Spring 4.3.2 Hibernate(HQL)迁移到Spring Boot 1.4.1 Hibernate(JPA)HikariCP连接池,并且在批量插入方面遇到问题。我需要保存1000到527 000个元素的大列表。 当我只保存一个实体的批次,没有任何依赖项(例如:类的5000个元素)时,一切都很好。 但是,如果我尝试同时保存子实体和父实体(只需为其设置),我会得到例外: 但

  • 问题内容: 我的应用程序的Web UI层中有一个JPA实体实例。我想随时知道此实体是否已经保存在数据库中或仅存在于用户会话中。 它将在业务层中,我将使用entitymanager.contains(Entity)方法,但是在我的UI层中,我认为我需要一个额外的属性来指示实体是否已保存。如何实施?我目前正在考虑以下选择: 由数据库设置默认值的JPA属性,但是每次更新后是否会强制进行新的读取? 在我的

  • 我是Spring BootJPA的新手,正在努力找出多个实体之间的关系。 我有一个用户实体、一个产品实体和一个评论实体。一个用户有很多评论。一个产品有很多评论。评论有一个产品和一个用户。 目前,我正在为用户使用一对多的关系 我的问题: 如何在不删除产品实体和用户实体的情况下删除审阅实体? 我应该使用哪种级联类型? 用户实体: 产品实体: 审查实体: 用户控制器: 用户服务: 简单运行: 我认为我不

  • 问题内容: 下面是一段代码,它是功能解密和加密程序的一部分。 如您所见,两个变量i和j首先被视为字符串,以便在任何一位数字前添加一个0(作为字符串)。然后将这些变量组合成一个四位数的数字(仍为字符串)。在程序的后面,在函数中使用创建的数字,因为s删除所有前导零。 我的问题:是否可以强制python保持s的前导零?我已经并且继续在线搜索。 编辑 为了帮助人们,我将程序的加密部分包括在内。这就是问题所

  • 问题内容: 当我对sudo使用任何命令时,环境变量不存在。例如,设置HTTP_PROXY后,如果不使用,该命令可以正常工作。但是,如果我键入它说它不能绕过代理设置。 问题答案: 技巧是通过命令将环境变量添加到文件并添加以下行: 摘自ArchLinux Wiki 。 对于Ubuntu 14,您需要在单独的行中指定,因为它会返回多变量行的错误: