2017-03-21 5 views
4

ich nächste Fehler haben: nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.Model.entities, could not initialize proxy - no SessionHibernate: LazyInitializationException: Fehler beim Initialisieren einer Sammlung von Rollen. Konnte nicht Proxy initialisieren - keine Session

Meine Model Einheit:

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); 
    } 

} 

Und ich habe eine Service-Klasse:

@Service 
@Transactional 
class ServiceImpl implements Service { 
    @Override 
    public void process(Model model) { 
     ... 
     model.addEntity(createEntity()); 
     ... 
    } 
} 

ich Dienst habe Aufruf von eine andere Service-Methode:

@Override 
@JmsListener(destination = "listener") 
public void handle(final Message message) throws Exception { 
    Model model = modelService.getById(message.getModelId()); 
    serviceImpl.process(model); 
    modelService.update(model); 
} 

Aber wenn ich versuche, diese Methode aufzurufen, bekomme ich Ausnahme in Zeile entities.add(entity); auch die gleiche Ausnahme tritt auf, wenn ich getEntities() auf model aufrufen. Ich habe den Transaktionsmanager überprüft und er ist korrekt konfiguriert und die Transaktion ist in diesem Schritt vorhanden. Auch ich habe tonnenweise Antworten auf stackoverflow geprüft, die mit dieser Ausnahme verbunden sind, aber nichts nützliches.

Was könnte die Ursache dafür sein?

+0

Wenn Sie sagen "_transaction exists on this step_" bedeutet das, dass Sie überprüft haben, dass eine Transaktion wirklich offen ist, wie zum Beispiel http://stackoverflow.com/a/42584751/3517383? – gabrielgiussi

+0

@gabrielgiussi ja –

+0

Ist Entität ein neues Objekt? Wenn dies der Fall ist, müssen Sie das Entitätsobjekt zuerst in der Datenbank speichern und dann in der Liste der Entitäten hinzufügen. – Dimitri

Antwort

4

Es scheint, dass das Modell eine losgelöste Einheit ist.

Versuchen zu fusionieren und Operationen auf einem Merge-Instanz durchführen:

@Override 
public void process(Model model) { 
    ... 
    Model mergedModel = session.merge(model); 

    mergedModel.addEntity(createEntity()); 
    ... 
} 
+0

In der Tat, oder öffnen Sie die Transaktion in einem ersten Dienst, der alle anderen Dienste aufruft. – gabrielgiussi

+1

Eigentlich möchte ich kein Session-Objekt verwenden. Kurz bevor ich den Prozess anrufe, mache ich ModelService.getModelById (modelId); und es gibt mir Objekt aus der Datenbank –

+1

Ok, aber das ist getan, ich nehme an, in einer separaten Transaktion .. Sobald Sie Prozess-Methode aufrufen das Modell ist bereits eine getrennte Einheit und Persistenz-Provider verwaltet es nicht mehr. Sie müssen es zurückführen. Oder machen Sie einfach die Abfrage innerhalb der Prozessmethode. –

1

So wie @Maciej Kowalski nach dem ersten @Transactional Lese erwähnt meiner model es ist bereits in deatached Zustand und rufen entities von einem anderen @Transactional Verfahren zu erhalten ist fehlgeschlagen mit LazyInitializationException.

Ich habe meinen Dienst ein wenig verändert model aus der Datenbank in derselben Transaktion zu erhalten:

@Service 
@Transactional 
class ServiceImpl implements Service { 
    @Override 
    public void process(long modelId) { 
     ... 
     Model model = modelDao.get(modelId); 
     model.addEntity(createEntity()); 
     ... 
    } 
} 

Jetzt ist alles wie erwartet funktioniert.

+0

Sie sollten Maciej Antwort als richtig markieren. – gabrielgiussi

Verwandte Themen