Reputation: 13
I'm new to spring boot. I searched a lot but I coudn't figure out what I'm missing here
I have three entities
Student
@Getter
@Setter
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "STUDENT_PK_SEQ")
@SequenceGenerator(name = "STUDENT_PK_SEQ", sequenceName = "STUDENT_PK_SEQ", allocationSize = 1)
private Long id;
private String title;
@OneToOne(cascade = CascadeType.ALL)
private ClassInstance classInstance;
}
Class
@Getter
@Setter
@Entity
@Table(name = "class")
public class Class {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CLASS_PK_SEQ")
@SequenceGenerator(name = "CLASS_PK_SEQ", sequenceName = "CLASS_PK_SEQ", allocationSize = 1)
private Long id;
private String title;
@OneToMany(mappedBy = "class")
@JsonIgnoreProperties(value = {"class"}, allowSetters = true)
private Collection<ClassInstance> classInstances;
}
ClassInstance
@Getter
@Setter
@Entity
@Table(name = "class_instance")
public class ClassInstance {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CLASS_INSTANCE_PK_SEQ")
@SequenceGenerator(name = "CLASS_INSTANCE_PK_SEQ", sequenceName = "CLASS_INSTANCE_PK_SEQ", allocationSize = 1)
private Long id;
private String title;
@ManyToOne
private Class class;
@OneToOne(cascade = CascadeType.ALL)
private Student student;
}
The problem occurs when I would like to assign an existing Student
to ClassIntance
@Transactional
@Override
public ClassInstanceDto createClassInstance(Long idClass, Long idStudent) {
if(idClass == null || idStudent == null){
throw new ApiRequestException(Constants.INVALID_ID, HttpStatus.PRECONDITION_FAILED);
}
Optional<Class> class = classRepository.findById(idClass);
if(class.isPresent()) {
Student student = studentRepository.getById(idStudent);
student.setTitle("X");
studentRepository.save(student);
ClassInstance classInstance = new ClassInstance();
classInstance.setClass(class.get());
classInstance.setStudent(student);
ClassInstance result = classInstanceRepository.save(classInstance);
//start //if I remove this part, it works
student.setClassInstance(result);
studentRepository.save(student);
//end
return classInstanceMapper.toClassInstanceDto(result);
} else {
throw new ApiRequestException(Constants.CLASS_NOT_FOUND, HttpStatus.NOT_FOUND);
}
}
I can't even understand what's the error message all I got is that
ma.company.app.mapper.ClassInstanceMapperImpl.toClassInstanceDto(ClassInstanceMapperImpl.java:37) ~[classes/:na]
at ma.company.app.mapper.ClassInstanceMapperImpl.studentToStudentDto(ClassInstanceMapperImpl.java:162) ~[classes/:na]
ma.company.app.mapper.ClassInstanceMapperImpl.toClassInstanceDto(ClassInstanceMapperImpl.java:37) ~[classes/:na]
at ma.company.app.mapper.ClassInstanceMapperImpl.studentToStudentDto(ClassInstanceMapperImpl.java:162) ~[classes/:na]
ma.company.app.mapper.ClassInstanceMapperImpl.toClassInstanceDto(ClassInstanceMapperImpl.java:37) ~[classes/:na]
at ma.company.app.mapper.ClassInstanceMapperImpl.studentToStudentDto(ClassInstanceMapperImpl.java:162) ~[classes/:na]
ma.company.app.mapper.ClassInstanceMapperImpl.toClassInstanceDto(ClassInstanceMapperImpl.java:37) ~[classes/:na]
at ma.company.app.mapper.ClassInstanceMapperImpl.studentToStudentDto(ClassInstanceMapperImpl.java:162) ~[classes/:na]
ma.company.app.mapper.ClassInstanceMapperImpl.toClassInstanceDto(ClassInstanceMapperImpl.java:37) ~[classes/:na]
at ma.company.app.mapper.ClassInstanceMapperImpl.studentToStudentDto(ClassInstanceMapperImpl.java:162) ~[classes/:na]
UPDATE here is my mapper
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface ClassInstanceMapper {
ClassInstanceDto toClassInstanceDto(ClassInstance classInstance);
ClassInstance toClassInstance(ClassInstanceDto classInstanceDto);
List<ClassInstanceDto> toClassInstanceDtos(List<ClassInstance> classInstances);
List<ClassInstance> toClassInstances(List<ClassInstanceDto> classInstanceDtos);
}
ClassInstanceDto
@Getter
@Setter
public class ClassInstanceDto {
private Long id;
private StudentDto student;
private ClassDto class;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassInstanceDto that = (ClassInstanceDto) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
StudentDto
@Getter
@Setter
public class StudentDto {
private Long id;
private String title;
private ClassInstanceDto ClassInstance;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StudentDto that = (StudentDto) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
Thanks in advance!
Upvotes: 0
Views: 800
Reputation: 5872
You have a recursive loop happening during the mapping. I'm not certain about the inner workings of MapStruct, but if it's using ObjectMapper, it would probably honor JsonManageReference and JsonBackReference annotations.
Assuming that ClassInstance is the parent,
@JsonManagedReference
@OneToOne(cascade = CascadeType.ALL)
private Student student;
One the "child" side
@JsonBackReference
@OneToOne(cascade = CascadeType.ALL)
private ClassInstance classInstance;
Do this also for your OneToMany/ManyToOne mappings. Also, I would strongly encourage you not to name your class, Class
.
Upvotes: 2