web-dev-qa-db-fra.com

Hibernate: LazyInitializationException: échec de l'initialisation paresseuse d'une collection de rôles. Impossible d'initialiser le proxy - pas de session

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?

12
Orest

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());
    ...
}
9
Maciej Kowalski

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.

4
Orest