JPA (Hibernate) - Sitzung/Transaktion und lazy loading

Ich habe ein Java-EE-Projekt und die MySQL-Datenbank verwaltet, die mit einem ORM. Ich arbeitete viel mit Hibernate zu lernen, was ich falsch mache und ich glaube, ich verstehe Sitzung/Transaktion, aber ich weiß nicht, wie ich dieses Problem lösen, in meinem Fall/Architektur.

Habe ich ein Projekt und eine Person, die in eine bidirektionale n:m Beziehung mit einer join-Tabelle. Das Projekt wird von der mapping-Besitzer. Jetzt will ich das löschen einer Person, die verbunden ist mit einem Projekt.

So, ich dachte, ich kann dies tun:

Person person = findPersonById(personId);
Set<Project> projects = person.getProjects();
Iterator<Project> iterator = projects.iterator();
while (iterator.hasNext()) {
    Project project = iterator.next();
    if (project.getPersons().contains(person)) {
        project.getPersons().remove(person);
        projectDao.updateProject(project);
    }
}
personDao.removePerson(personId);

Aber ich bekomme eine Fehlermeldung in dieser Zeile:

Iterator<Project> iterator = projects.iterator();

Aber es scheint, dass es hat zu tun mit:

Person person = findPersonById(personId);

und:

public Person findPersonById(int personId) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session sess = sessionFactory.getCurrentSession();

    Transaction tx = sess.beginTransaction();
    try {
        Person person = (Person)sess.createQuery("from Person where id = "+personId).list().get(0);
        tx.commit();
        return person;
    }
    catch (IndexOutOfBoundsException ex) {
        return null;
    }
}

Hier mache ich eine Transaktion und nur die person-Objekt, aber keine entsprechenden Projekte. Und der iterator wird versuchen, Sie zu bekommen, kann aber nicht, weil meine Transaktion/Sitzung ist geschlossen.
Dies ist, weil mein Architektur:

Habe ich:
IPersonService -> IPersonImplementation -> IPersonDao -> IPersonDaoImplementation
und nur die Methode in IPersonDaoImplementation öffnet und schließt die Transaktion. Also in meinem ServicePersonImplementation, ich kann nicht mehrere DB-bezogene Sachen (ich will nicht zu haben, FetchType.BEGIERIG in meine @ManyToMany-annotation, denn diese laden würde zu viel nicht benötigte Sachen). Denn einmal gibt es aus meiner DaoImplementation kann ich keine anderen Aktionen auf der zurückgegebenen person (in meinem Fall alle Projekte, die gemeinsam mit dieser person).

Also, was kann ich tun in meinem Fall?

Beste Grüße Tim.

Update:
PersonDaoImpl, remove-Methode:

public void removePerson(int personId){
    Person p = findPersonById(personId);

    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session sess = sessionFactory.getCurrentSession();

    Transaction tx = sess.beginTransaction();
    sess.delete(p);
    sess.flush();
    tx.commit();
}

- Trace des Fehlers:

FEHLER: org.hibernate.LazyInitializationException - fehlgeschlagen zu faul initialize a collection of role: com.testdomain.testproject.domain.Person.Projekte, keine Sitzung oder die Sitzung geschlossen wurde
org.hibernate.LazyInitializationException: failed to faul initialize a collection of role: com.testdomain.testproject.domain.Person.Projekte, keine Sitzung oder die Sitzung geschlossen wurde
bei org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
bei org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionifnotconnected(AbstractPersistentCollection.java:375)
bei org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
bei org.hibernate.Sammlung.AbstractPersistentCollection.Lesen(AbstractPersistentCollection.java:111)
bei org.hibernate.Sammlung.PersistentSet.iterator(PersistentSet.java:186)
bei com.testdomain.testproject.dao.impl.PersonDaoImplHibernate.removePerson(PersonDaoImplHibernate.java:71)
bei com.testdomain.testproject.service.impl.PersonServiceImpl.removePerson(PersonServiceImpl.java:88)
bei com.testdomain.testproject.service.PersonTest.testRemovePerson(PersonTest.java:180)
bei der sun.reflektieren.NativeMethodAccessorImpl.invoke0(Native-Methode)
bei der sun.reflektieren.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
bei der sun.reflektieren.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
bei java.lang.reflektieren.Methode.invoke(Method.java:597)
bei org.junit.die Läufer.Modell.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
bei org.junit.intern.die Läufer.Modell.ReflectiveCallable.run(ReflectiveCallable.java:15)
bei org.junit.die Läufer.Modell.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
bei org.junit.intern.die Läufer.Aussagen.InvokeMethod.bewerten(InvokeMethod.java:20)
bei org.junit.die Läufer.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
bei org.junit.die Läufer.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
bei org.junit.die Läufer.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
bei org.junit.die Läufer.ParentRunner$3.run(ParentRunner.java:193)
bei org.junit.die Läufer.ParentRunner$1.Zeitplan(ParentRunner.java:52)
bei org.junit.die Läufer.ParentRunner.runChildren(ParentRunner.java:191)
bei org.junit.die Läufer.ParentRunner.access$000(ParentRunner.java:42)
bei org.junit.die Läufer.ParentRunner$2.bewerten(ParentRunner.java:184)
bei org.junit.intern.die Läufer.Aussagen.RunBefores.bewerten(RunBefores.java:28)
bei org.junit.die Läufer.ParentRunner.run(ParentRunner.java:236)
bei org.eclipse.jdt.intern.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
bei org.eclipse.jdt.intern.junit.runner.TestExecution.run(TestExecution.java:38)
bei org.eclipse.jdt.intern.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
bei org.eclipse.jdt.intern.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
bei org.eclipse.jdt.intern.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
bei org.eclipse.jdt.intern.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Fehlgeschlagen löschen Person: fehlgeschlagen zu faul initialize a collection of role: com.testdomain.testproject.domain.Person.Projekte, keine Sitzung oder die Sitzung geschlossen wurde

  • Was ist der Fehler???
  • Lazy-Initialisierung, oder wenn ich einige Veränderungen bekomme ich die Fehlermeldung, dass es nicht gelöscht werden können, weil der foreign key-Einschränkungen, aber ich verstehe jetzt, warum das problem Auftritt, aber wie kann ich das lösen das elegant? Wenn die iteration wird in der Transaktion habe ich nicht dieses problem haben?!
  • Richtig, Sie wollen entfernen Sie die Person aus, die alle Projekte innerhalb der remove-Methode aus der interface PersonDao
  • Ich fügte hinzu, die removePerson Methode, um meine erste post. Also, was sollte ich dort auftreten? Erstellen Sie eine SQL-Anweisung?
  • Siehe meine aktualisierte Antwort unten.
  • Können Sie nach dem vollständigen stacktrace der Ausnahme?
  • Aber natürlich, ich habe es in meinem ersten post.

InformationsquelleAutor Tim | 2010-10-14
Schreibe einen Kommentar