JPA hibernate 保存 spring/JPA/Java 上的 ConcurrentModificationException

Raj*_*wal 1 hibernate jpa spring-data-jpa spring-boot

有两个实体

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

2.主题(父/所有者)(@ManyToOne)

通过邮递员,我传递了储物柜实体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

Run Code Online (Sandbox Code Playgroud)

第二实体

@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
Run Code Online (Sandbox Code Playgroud)

现在是存储库接口

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

public interface SubjectsRepo2 extends CrudRepository<Subjects,Integer>{
}
Run Code Online (Sandbox Code Playgroud)

现在是控制器方法

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";
}
Run Code Online (Sandbox Code Playgroud)

我传递的 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]
Run Code Online (Sandbox Code Playgroud)

Cod*_*der 5

这里有几点需要注意。

  • 首先,您正在使用迭代器并尝试修改对象内容并保存它们。使用 ListIterator 允许将修改后的值设置回列表。
  • 其次,您正在JPA save 循环内使用。使用 saveAndFlush这样 hibernate 就不会保留对象信息。

您的代码通常如下所示:

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";
    }
Run Code Online (Sandbox Code Playgroud)