在Spring JPA中执行Hibernate.initialize()时获取并发修改异常

时间:2019-07-12 13:08:40

标签: java hibernate spring-boot spring-data-jpa

我正在使用带有spring data jpa的spring boot应用程序。当我遍历对象时,我遇到了并发修改异常。

当我遍历Submitting.getPages()时,我遇到了并发ModificationException。

我厌倦了检查null和空但没有运气

@Override
    public void processCopyAttachmentsToProcessAttachments(int processId) {
        Optional<Process> processOpt = processRepository.findById(processId);
        if (processOpt.isEmpty()) {

            return;
        }
        Process process = processOpt.get();
        Hibernate.initialize(process.getSubmissons());
        List<Submission> submissions = process.getSubmissons();
        if (submissions == null || submissions.isEmpty())
            return;

        for (Submission submission : submissions) {
            Hibernate.initialize(submission.getPages());        
            if (submission.getPages() == null || submission.getPages().isEmpty())
                return;
            for (SubmissionPage submissionPage : submission.getPages()) {           
                Hibernate.initialize(submissionPage.getAttachments());
                if (submissionPage.getAttachments() == null || submissionPage.getAttachments().isEmpty())
                    return;         
                for (SubmissionPageAttachment submissionPageAttachment : submissionPage.getAttachments()) {
                    ProcessAttachment processAttachment = new ProcessAttachment();
                    processAttachment.setDocumentId(submissionPageAttachment.getDocumentId());
                    processAttachment.setDocumentType(submissionPageAttachment.getDocumentType());
                    processAttachment.setProcess(process);
                    processAttachmentRepository.save(processAttachment);
                }
            }
        }
    }

如何解决此问题?

1 个答案:

答案 0 :(得分:1)

再检查一次您的问题,我认为罪魁祸首是Hibernate.initialize。因为它修改了传递的对象。

这是该方法的源代码。正如我们清楚地看到的那样,它修改了它们的状态,并且由于我们知道ConcurrentModificationException会在迭代过程中更改内容时发生,这显然是原因。

    public static void initialize(Object proxy) throws HibernateException {
        if ( proxy == null ) {
            return;
        }

        if ( proxy instanceof HibernateProxy ) {
            ( (HibernateProxy) proxy ).getHibernateLazyInitializer().initialize();
        }
        else if ( proxy instanceof PersistentCollection ) {
            ( (PersistentCollection) proxy ).forceInitialization();
        }
        else if ( proxy instanceof PersistentAttributeInterceptable ) {
            final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) proxy;
            final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
            if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
                ( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( proxy, null );
            }
        }
    }

使用常规的for循环时,它一次访问集合中的一个对象,因此不会出现异常。