hibernatespring-bootjpaspring-data-jpa

ConcurrentModificationException on JPA hibernate save spring/JPA/Java


There are two entities

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

2.Subjects(parent/owner)(@ManyToOne)

Through postman i am passing the Locker entity id and through this i am accessing the Subjects and trying to update a particular thing but i am getting the error and i am not even creating new i am just updating it and everything is working insertion and deletion except this case

@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

2nd entity

@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

and now repository interfaces

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

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

and now the controller method

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";
}

I am passing the id which is already present in the database but still it is giving this error

java.util.ConcurrentModificationException: null

stack trace

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]

Solution

  • Couple things to note here.

    Your code will typically look as specified below:

    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";
        }