J'ai la prochaine erreur: nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.Model.entities, could not initialize proxy - no Session
Mon Model
entité:
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);
}
}
Et j'ai une classe de service:
@Service
@Transactional
class ServiceImpl implements Service {
@Override
public void process(Model model) {
...
model.addEntity(createEntity());
...
}
}
J'appelle le service à partir d'une autre méthode de service:
@Override
@JmsListener(destination = "listener")
public void handle(final Message message) throws Exception {
Model model = modelService.getById(message.getModelId());
serviceImpl.process(model);
modelService.update(model);
}
Mais lorsque j'essaie d'appeler cette méthode, j'obtiens une exception sur la ligne entities.add(entity);
également la même exception se produit lorsque j'appelle getEntities()
sur model
. J'ai vérifié le gestionnaire de transactions et il est correctement configuré et la transaction existe à cette étape. J'ai également vérifié des tonnes de réponses sur stackoverflow liées à cette exception mais rien d'utile.
Quelle pourrait en être la cause?
Il semble que le modèle soit une entité détachée.
Essayez de fusionner et d'effectuer des opérations sur une instance de fusion:
@Override
public void process(Model model) {
...
Model mergedModel = session.merge(model);
mergedModel.addEntity(createEntity());
...
}
Donc, comme @Maciej Kowalski l'a mentionné après le premier @Transactional
lire mon model
il est déjà à l'état détaché et appeler pour obtenir entities
d'un autre @Transactional
La méthode a échoué avec LazyInitializationException
.
J'ai un peu changé mon service pour obtenir model
de la base de données dans la même transaction:
@Service
@Transactional
class ServiceImpl implements Service {
@Override
public void process(long modelId) {
...
Model model = modelDao.get(modelId);
model.addEntity(createEntity());
...
}
}
Maintenant, tout fonctionne comme prévu.