java - 您可以使用 JPA 和 Hibernate 在一个事务中进行批量删除吗?

标签 java hibernate jpa session transactions

所以,我一直在用头撞墙,试图加快从我的数据库中删除的过程。我对 Hibernate 比较陌生,我想知道是否可以在一个事务中执行多个操作。

我不太担心事务删除失败,所以回滚所有删除的想法不会打扰我。

如果提供表格说明有帮助,我也可以这样做。不过我的想法是,在删除每个 for 循环之外的内容之前,我必须先删除每个 for 循环中的内容。

我的代码

  private void deleteTrackItems() {
        Session session = m_databaseConnection.getSession();
        Transaction tx = null;
        try {

            final List<TrackItem> trackItems = loadAllTrackItemByTrackID(
                    track.getId(), session);

            // Deletes all Track Items for the given track
            List<Long> trackItemIds = new ArrayList();
            
            for (TrackItem trackItem : trackItems) {
                trackItemIds.add(trackItem.getId());

                // this is test code 189 through 214
                Set<TrackPoint> trackPoints = trackItem.getTrackPoints();

                for (TrackPoint trackPoint : trackPoints) {

                    // load track
                    final List<TrackPointDetail> trackPointDetails = loadAllTrackPointDetailByTrackID(
                            trackPoint.getId(), session);

                    for (TrackPointDetail trackPointDetail : trackPointDetails) {
                        // delete track point details
                        deleteObject(trackPointDetail, session);
                    }

                    // delete track point
                    deleteObject(trackPoint, session);
                }

                // get the track informations
                final Set<TrackInformation> trackInformations = trackItem
                        .getTrackInformations();

                // for each track information
                for (TrackInformation trackInformation : trackInformations) {
                    deleteTrackInformation(trackInformation, session);
                }
                deleteObject(trackItem, session);
            }
        }
        catch (Exception ex) {
            System.out.println(ex);
            tx.rollback();
        }
        finally {
            if (session != null) {
                session.close();
            }
        }
    }
    
/**
 * @param p_objectToDelete The object to delete
 * @param p_session the hibernate session
 * @return Returns the {@link Runnable}
 */
protected void deleteObject(Object p_objectToDelete, final Session p_session) {

    // get the transaction
    final Transaction transaction = p_session.getTransaction();
    try {
        LOGGER.info("Deleting object: " + p_objectToDelete.getClass());
        transaction.begin();
        p_session.delete(p_objectToDelete);
        transaction.commit();
        LOGGER.info("Deleted object: " + p_objectToDelete.getClass());
    }
    catch (Exception exception) {
        transaction.rollback();
        LOGGER.error(exception);
    }
}

因为这些操作中的每一个都在每次删除后执行提交,所以我想知道是否可以在更多的批量操作中执行此操作。

我当时想做的是将我的提交从我的 deleteObject 函数中拉出来,并将它放在对每个对象调用 delete 的 for 循环的末尾。

所以

final Transaction tx = session.getTransaction();
transaction.begin();
try{
   for(Object object : objects){
      session.delete(object);
   }
   tx.commit();
}catch(Exception ex){
   System.out.println(ex);
   tx.rollback();
}

我的另一种批量删除解决方案是使用 hibernate SQLQuery,我只获取每个对象的 ID,将它们存储在列表中,然后在一个查询中以这种方式进行批量删除。但是,我觉得当我执行该查询时,由于序列扫描,我的 where id in (?,?,?,?,?) 列表需要更多时间。

我觉得应该有一种使用 hibernates session.delete() 进行批量删除的简单方法。非常感谢任何想法。

最佳答案

使用 Hibernate 和 JPA 执行批量删除的常用方法与您在上一个解决方案中提出的完全相同 - HQL/JPQL 中的批量删除查询

从 MyEntity 中删除 e.id IN (:ids)

这应该是迄今为止最高效的一种,因为 Hibernate 不需要加载和实例化实体。

考虑将批量删除放入它自己的事务方法中,并在您的其他方法中尽快调用该方法 - 持久性上下文不会随查询结果更新,因此您希望防止持久性上下文包含陈旧的数据。

关于java - 您可以使用 JPA 和 Hibernate 在一个事务中进行批量删除吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24914370/

相关文章:

java - 以天为单位的日期差异限制 Hibernate

Hibernate/JPA 调用 equals() 触发延迟加载异常

java - 我可以在 JPA native sql 查询中检索列名吗?

java - 返回使用正则表达式找到的字符串

java - 调度传入 RPC 调用时出现异常

java - Datanucleus在GAE中使用Maven增强,构建失败

java - spring mvc模块不更新记录

java - 我的 s3 存储桶中的图像不会在浏览器中打开,它们只会下载

java - 双向 hibernate 关系

java - 如何在BaseDao中获取EntityManager(Maven+JSF+hibernate)