1

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]
2
  • The stacktrace says m23. You have provided m25. Commented Aug 22, 2019 at 6:31
  • yes same code and different method name its the same Commented Aug 22, 2019 at 8:55

3 Answers 3

5

Couple things to note here.

  • First, You are using an iterator and trying to modify the object contents and save them. Use ListIterator which allows setting modified values back to the list.
  • Second, you are using JPA save inside a loop. Use saveAndFlush so that hibernate won't persist object information.

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";
    }
Sign up to request clarification or add additional context in comments.

4 Comments

@RajatAgrawal which implementation solved the issue?
your solution contains clean code plus you have explained it in a good way also 👍👍
Happy to help :)
best apps have this type of returns. Thanks for sharing, helped me to solve something similar
1

You're modifying the underlying collection that you are iterating while also modifying the value of an object you're iterating over that is part of the same collection, which is causing your ConcurrentModificationException.

See the line in your stack trace:

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

and you're using and ArrayList.

Try the following:

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

3 Comments

hey i tried this thing but still it is giving error(same) and also tried this with List
Okay, I actually tried to reproduce this locally but can't. Can you just not use the iterator so then and that should solve the issue. for(int i = 0; i < sub.size(); i++) { Subjects sub 1= sub.get(0); if(sub1.getId() == 3){...}
hey yes man if i use for loop instead of iterator still it is working thanks @Rob Scully
1

The reason I got this was having one of the EntityListener namely @PostUpdate or @PostPersist performing an operation that uses a Spring JPA repository that will eventually touch entity manager. That is actually not allowed, so what I had to do was replace the usage of JPA objects on the entity listener with JOOQ as the data at that point is flushed due to being @PostXXX and therefore the generated values are already populated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.