【问题标题】:ConcurrentModificationException on JPA hibernate save spring/JPA/JavaJPA hibernate 上的 ConcurrentModificationException 保存 spring/JPA/Java
【发布时间】:2019-08-21 10:29:50
【问题描述】:

有两个实体

1.Locker(child)(@OneToMany(mappedBy))

2.Subjects(父母/所有者)(@ManyToOne)

通过邮递员,我传递了 Locker 实体 ID,通过它我正在访问主题并尝试更新特定的东西,但我收到错误,我什至没有创建新的,我只是在更新它,一切都在工作插入除本例外删除

@Entity
public class Locker {

    @Id
    @GeneratedValue
    private int id;
    private String lockerno;

    @OneToMany(mappedBy="lockey",cascade= {CascadeType.ALL})
    private List<Subjects> subjects;

    //getters andsetter and constructors

第二个实体

@Entity
public class Subjects {

    @Id
    @GeneratedValue
    private int id;
    private String subname;
    private String marks;

    @ManyToOne(cascade= {CascadeType.MERGE,CascadeType.REMOVE,CascadeType.REFRESH})
    private Locker lockey;

    //getters and setter constructors

现在是存储库接口

public interface LockerRepo extends CrudRepository<Locker,Integer>{
}

public interface SubjectsRepo2 extends CrudRepository<Subjects,Integer>{
}

现在是控制器方法

public String m25(@RequestParam("id") int id) throws Exception {

    Optional<Locker> lock=lockerrepo.findById(id);
    Locker ll=lock.get();
    ArrayList<Subjects> sub=new ArrayList<> (ll.getSubjects());

    Iterator itr=sub.iterator();
    while (itr.hasNext()) {
        Subjects sub1=(Subjects) itr.next();
        System.out.println(sub1.getId());
        if(sub1.getId()==3) {
            sub1.setMarks("91");
            subrepo.save(sub1);     
        }
    }
    return "updation done man";
}

我正在传递数据库中已经存在的 id,但它仍然给出此错误

java.util.ConcurrentModificationException: null

堆栈跟踪

java.util.ConcurrentModificationException: null
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[na:1.8.0_181]
        at java.util.ArrayList$Itr.next(Unknown Source) ~[na:1.8.0_181]
        at org.hibernate.collection.internal.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:850) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
        at com.example.demo.controller.MainController.m23(MainController.java:86) ~[classes/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_181]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_181]
        at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_181]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]

【问题讨论】:

  • 堆栈跟踪显示m23。您提供了m25
  • 是的,相同的代码和不同的方法名称相同

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


【解决方案1】:

这里有几点需要注意。

  • 首先,您正在使用迭代器并尝试修改对象 内容并保存。使用允许设置的 ListIterator 修改后的值返回列表。
  • 其次,您在循环中使用JPA save。利用 saveAndFlush 这样休眠就不会持久化对象信息。

您的代码通常如下所示:

public String m25(@RequestParam("id") int id) throws Exception {
        Optional<Locker> lock=lockerrepo.findById(id);
        Locker ll=lock.get();
        ArrayList<Subjects> sub=new ArrayList<> (ll.getSubjects());
        ListIterator itr=sub.listIterator();
        while (itr.hasNext()) {
            Subjects sub1=(Subjects) itr.next();
            System.out.println(sub1.getId());
            if(sub1.getId()==3) {
                sub1.setMarks("91");
                itr.set(sub1);
                subrepo.saveAndFlush(sub1);
            }
        }
        return "updation done man";
    }

【讨论】:

  • @RajatAgrawal 哪个实现解决了这个问题?
  • 您的解决方案包含干净的代码,而且您也以很好的方式解释了它??
  • 乐于助人:)
【解决方案2】:

您正在修改您正在迭代的基础集合,同时还修改了您正在迭代的对象的值,该对象是同一集合的一部分,这会导致您的 ConcurrentModificationException。

查看堆栈跟踪中的行:

在 java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[na:1.8.0_181]

而你正在使用 ArrayList。

尝试以下方法:

for(int i = 0; i < sub.size(); i++) { Subjects sub 1= sub.get(0); 
    if(sub1.getId() == 3)
    {...}

【讨论】:

  • 嘿,我试过这个东西,但它仍然给出错误(相同)并且还用 List 试过这个
  • 好的,我实际上尝试在本地重现此内容,但不能。你能不能不使用迭代器,那应该可以解决问题。 for(int i = 0; i
  • 嘿,是的,如果我使用 for 循环而不是迭代器,它仍然可以工作,谢谢@Rob Scully
猜你喜欢
  • 2018-12-02
  • 2019-01-12
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 2019-09-09
  • 1970-01-01
相关资源
最近更新 更多