tengo este error:
2020-11-16 22:36:09.313 ERROR 19428 --- [nio-8080-exec-5] oaccC[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: collection was evicted; nested exception is org.hibernate.HibernateException: collection was evicted] with root cause org.hibernate.HibernateException: collection was evicted at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:43) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]Creo una aplicación API REST, mis entidades tienen esta composición:
public class Label { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long Id; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "label") private Set<Release> releases; public class Release { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL) @JoinColumn(name = "label_id") private Label label;Después de la tercera solicitud API-REST para crear datos de asociación de lanzamiento/etiqueta, tengo el error en la parte superior
RestController:
@PostMapping(value = "/release", consumes = "application/json", produces = "application/json") Release newRelease(@RequestBody ReleaseDto releaseDto) { return releaseService.addRelease(releaseDto); }Servicio de liberación:
@Service("ReleaseService") public class ReleaseServiceImpl implements ReleaseService{ @Autowired ReleaseRepository repository; @Autowired LabelRepository labelRepository; @Override public Release addRelease(ReleaseDto releaseDto) { Release release = new Release(); Optional<Label> label = labelRepository.findById(releaseDto.getLabel_id()); if(label.isPresent()){ release.setName(releaseDto.getName()); release.setLabel(label.get()); repository.save(release); } return release; }Estoy confundido, ¿tal vez debo implementar un administrador de entidades?
Saludos.
@EqualsAndHashCode.Exclude @ToString.ExcludeHe agregado estas dos anotaciones para el objeto @onetomany y mi error desapareció. Pero no sé cómo.
Como primera propuesta, recomendaría cambiar esta línea:
release = repository.save(release)El método save devuelve un objeto actualizado de la entidad, por lo que al devolver el "no actualizado", puede haber problemas al intentar serializar la respuesta.
Después de nuestra discusión, probablemente la eliminación CascadeType.ALL fue el problema aquí: Hibernate intentó hacer algo de magia con las entidades relacionadas, que no estaban sincronizadas.
Tal vez también desee crear un DTO para la Respuesta, ya que es una buena práctica separar esto de la entidad.
Usar FetchType.EAGER generalmente tampoco es una buena idea; algunas notas sobre esto https://vladmihalcea.com/eager-fetching-is-a-code-smell/ . Si cambia esto, probablemente necesite obtener las entidades relacionadas manualmente en el servicio, cambiando a un DTO separado y esto no es un problema de todos modos.
Puede consultar https://bootify.io , puede crear una API REST de ejemplo (pero no con su punto final personalizado de todos modos).