Tengo el siguiente error: nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.Model.entities, could not initialize proxy - no Session
Mi entidad Model :
class Model { ... @OneToMany(fetch = FetchType.LAZY, mappedBy = "model", orphanRemoval = true) @Cascade(CascadeType.ALL) @Fetch(value = FetchMode.SUBSELECT) public Set<Entity> getEntities() { return entities; } public void addEntity(Entity entity) { entity.setModel(this); entities.add(entity); } }Y tengo una clase de servicio:
@Service @Transactional class ServiceImpl implements Service { @Override public void process(Model model) { ... model.addEntity(createEntity()); ... } }Estoy llamando al servicio desde otro método de servicio:
@Override @JmsListener(destination = "listener") public void handle(final Message message) throws Exception { Model model = modelService.getById(message.getModelId()); serviceImpl.process(model); modelService.update(model); } Pero cuando trato de llamar a este método, obtengo una excepción en las entities.add(entity); también ocurre la misma excepción cuando llamo a getEntities() en el model . Revisé el administrador de transacciones y está configurado correctamente y la transacción existe en este paso. También revisé toneladas de respuestas en stackoverflow conectadas a esta excepción, pero nada útil.
¿Cuál podría ser la causa de ello?
Parece que el modelo es una entidad separada.
Intente fusionar y realizar operaciones en una instancia de fusión:
@Override public void process(Model model) { ... Model mergedModel = session.merge(model); mergedModel.addEntity(createEntity()); ... }Entonces, como @Maciej Kowalski mencionó después de la primera lectura @Transactional de mi model , ya está en un estado separado y la llamada para obtener entities de otro método @Transactional falló con LazyInitializationException .
Cambié un poco mi servicio para obtener el model de la base de datos en la misma transacción:
@Service @Transactional class ServiceImpl implements Service { @Override public void process(long modelId) { ... Model model = modelDao.get(modelId); model.addEntity(createEntity()); ... } }Ahora todo funciona como se esperaba.