10

Mein Code alle für den Benutzer bezogenen Informationen abruft:Hibernate konnte nicht Proxy initialisiert werden - keine Session

SessionFactory sessionFactory = HibernateUtilities.configureSessionFactory(); 
Session session = sessionFactory.openSession(); 
UserDetails ud = null; 
Set<Address> userAddress = null; 

try { 
    session.beginTransaction(); 
    ud = (UserDetails) session.get(UserDetails.class, 1); 
    userAddress = ud.getAddresses(); 
    session.getTransaction().commit(); 
} catch (HibernateException e) { 
    e.printStackTrace(); 
    session.getTransaction().rollback(); 
} finally { 
    session.close(); 
} 

System.out.println(ud.getName()); 

for(Address addr: userAddress){ 
    System.out.println("State " + addr.getState()); 
} 

Die ud.getAddresses() gibt einfach eine Menge von Address es des Benutzers.

Meine Frage ist: Warum hat das ud Objekt immer noch seinen Wert (zB Name), obwohl die Sitzung bereits geschlossen ist? ist eine Instanzvariable der Klasse . Aber warum kann ich seinen Wert nicht abrufen, aber ich kann reguläre Instanzvariablen der Klasse UserDetails abrufen?

ud.getAddresses() ist ein @EmbeddedCollection.

+0

"@EmbeddedCollection" - meinst du '@ ElementCollection'? –

Antwort

15
userAddress = ud.getAddresses(); 
session.getTransaction().commit(); 
for(Address addr: userAddress) { 

Die Hibernate Dokumentation für working with lazy associations nennt eindeutig als Fehler dieser Art von Zugriff aus. Sie können nur während der noch geöffneten Sitzung mit Objekten interagieren, die nur langsam verbunden sind. Dieser Teil der Dokumentation bietet auch Alternativen zum Zugriff auf solche lazy associated Mitglieder eines Objekts, und wir bevorzugen, den Abrufmodus als JOIN in den verwendeten Kriterien in unseren Anwendungen anzugeben.

+0

Also aus der Sicht, es fragt tatsächlich die Datenbank, wenn ich ud.getAddresses() aufrufen? – KyelJmD

3

Alle primitiven Eigenschaften der Klassen werden sofort geladen, sie können nicht faul sein, es sei denn, Sie verwenden Bytecode-Erweiterungen. Nur echte Assoziationen wie Ihre Sammlung können faul sein.

+0

Wie wäre es mit einer anderen Klasse? wird das als faule Initialisierung angesehen? – KyelJmD

+0

* Ja *, wenn es um MTO geht. Und * vielleicht * wenn es um OTO geht. –

+0

Was bedeuten MTO und OTO? – KyelJmD

11

stand ich das gleiche Problem in JPA/Hibernate, und es gibt zwei Möglichkeiten, dieses Problem zu lösen:

1/die Faulen standardmäßig deaktivieren, wie folgend:

@Entity 
@Proxy(lazy = false) 
public class Project { 
... 
} 

Natürlich Dieser Weg wird wegen des Leistungsproblems nicht empfohlen, daher können Sie den zweiten Weg gehen.

2/Sie können am Anfang Ihrer Methode setzen @Transactional, kann es Ihnen helfen, die Sitzung zu bleiben, oder ein anderes Verständnis, es die Pflicht der Sitzung übergeben Hibernate, wie folgend:

@Test 
@Transactional 
public void testSaveGroup() { 
    Department g = new Department(); 
    g.setName("XDG"); 
    assertNull(g.getId()); 
    this.groupRepo.save(g); 
    assertNotNull(g.getId()); 
    System.out.println(g.getId()); 
    Project dummyPrj = new Project(123L, "KSTA", new Date(), "NEW", "Helm AG", g); 
    this.projectRepo.save(dummyPrj); 
    // verify 
    List<Department> lst = this.groupRepo.findAll(); 
    Project savedPrj = this.projectRepo.getOne(123L); 
    Assert.assertEquals("XDG", savedPrj.getGroup().getName()); 
} 

Meine Antwort ist spät, aber hoffe, jemand anderem zu helfen :)

+0

Danke, @Transactional arbeitete für mich –

Verwandte Themen