'when i add opcion forEach method get java.util.ConcurrentModificationException: null
I have a problem, I have a question entity and an option entity, the relationship is one to many.
but when I want to add the options in the question, it shows me that error, as far as I could find, it is because the question entity is being used while it wants to be updated, but I still don't know how to fix it.
@Entity
public class Pregunta {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "cuestionario_id",nullable = false)
@JsonIgnore
private Cuestionario cuestionario;
private String descripcion;
@OneToMany(mappedBy = "pregunta",fetch = FetchType.EAGER,cascade=CascadeType.ALL)
private List<Opcion> opciones = new ArrayList<>();
public Pregunta() {
}
@JsonCreator
public Pregunta(@JsonProperty Cuestionario cuestionario,@JsonProperty String descripcion, List<Opcion> opciones) {
super();
this.cuestionario = cuestionario;
this.descripcion = descripcion;
this.opciones = opciones;
}
public int getId() {
return id;
}
public Cuestionario getCuestionario() {
return cuestionario;
}
public void setCuestionario(Cuestionario cuestionario) {
this.cuestionario = cuestionario;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public List<Opcion> getOpciones() {
return opciones;
}
public void setOpciones(List<Opcion> opciones) {
this.opciones = opciones;
}
public void addOpcion(Opcion opcion) {
this.opciones.add(opcion);
opcion.setPregunta(this);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
@Entity
public class Opcion {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private boolean correct;
private String content;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "pregunta_id",nullable = false)
@JsonIgnore
private Pregunta pregunta;
public Opcion(boolean correct, String content) {
super();
this.correct = correct;
//this.pregunta = pregunta;
this.content = content;
}
public Opcion() {}
public int getId() {
return id;
}
public boolean isCorrect() {
return correct;
}
public void setCorrect(boolean correct) {
this.correct = correct;
}
public String getContent() {
return content;
}
public Pregunta getPregunta() {
return pregunta;
}
public void setPregunta(Pregunta pregunta) {
this.pregunta = pregunta;
}
public void setContent(String content) {
this.content = content;
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
@Entity
public class Cuestionario {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(nullable = false)
private String name;
@OneToMany(mappedBy = "cuestionario",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private List<Pregunta> preguntas = new ArrayList<>();
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "tipo_cuestionario_id",nullable = false)
private TipoCuestionario tipoCuestionario;
@JsonCreator
public Cuestionario(@JsonProperty int id,@JsonProperty String name,@JsonProperty List<Pregunta> preguntas,@JsonProperty TipoCuestionario tipoCuestionario) {
super();
this.id = id;
this.name = name;
this.preguntas = preguntas;
this.tipoCuestionario = tipoCuestionario;
}
public Cuestionario() {}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Pregunta> getPreguntas() {
return preguntas;
}
public void setPreguntas(List<Pregunta> preguntas) {
this.preguntas = preguntas;
}
public TipoCuestionario getTipoCuestionario() {
return tipoCuestionario;
}
public void setTipoCuestionario(TipoCuestionario tipoCuestionario) {
this.tipoCuestionario = tipoCuestionario;
}
public void addPregunta(Pregunta pregunta) {
this.preguntas.add(pregunta);
pregunta.setCuestionario(this);
}
}
@Override
public Cuestionario createCuestionario(CuestionarioDto cuestionario) {
Cuestionario newCuestionario = new Cuestionario();
newCuestionario.setName(cuestionario.getName());
Optional<TipoCuestionario> tipoCuestionarioOpt = tipoCuestionarioRepository.findById(cuestionario.getTipoCuestionario());
if(tipoCuestionarioOpt.isPresent()) {
newCuestionario.setTipoCuestionario(tipoCuestionarioOpt.get());
}
cuestionario.getPreguntas().forEach(pregunta->newCuestionario.addPregunta(pregunta));
cuestionario.getPreguntas().forEach(pregunta->pregunta.getOpciones().forEach(opcion->pregunta.addOpcion(opcion)));
cuestionarioRepository.save(newCuestionario);
return newCuestionario;
}
Solution 1:[1]
I think problem is here
cuestionario.getPreguntas().forEach(pregunta->pregunta.getOpciones().forEach(opcion->pregunta.addOpcion(opcion)));
you iterate over pregunta.getOpciones() and perform pregunta.addOpcion(opcion)
so You modify collection while iterating over it
https://www.baeldung.com/java-concurrentmodificationexception
BTW it looks like You iterate over Opciones in pregunta and add opcion to pregunta you try to duplicate entries ?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lukwas |

