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]
Couple things to note here.
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";
}