10

Kodum kullanıcıya ilgili tüm bilgileri alır hayır Oturumu:hazırda vekil başlatılamadı -

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

ud.getAddresses() basitçe kullanıcının Address es kümesi döndürür.

Sorum şu: Oturum zaten kapalı olsa bile neden ud nesnesinin değeri (örn. Ad) hala geçerli? getAddresses(), UserDetails sınıfının bir örnek değişkeni. Ama neden onun değerini alamıyorum ama UserDetails sınıfının normal örnek değişkenlerini alabilirim?

ud.getAddresses()@EmbeddedCollection'dur.

+0

"@EmbeddedCollection" - "ElementCollection" demek istiyor musunuz? –

cevap

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

working with lazy associations için hazırda belgelerine açıkça hata olarak erişim bu tür sesleniyor. Tembel olarak ilişkili nesnelerle yalnızca oturum açıkken etkileşimde bulunabilirsiniz. Dokümantasyonun bu bölümü, aynı zamanda, bir nesnenin bu temassız ilişkili üyelerine erişim için alternatifler sağlar ve uygulamalarımızda, kullanılan ölçütlerde JOIN olarak getirme modunu belirtmeyi tercih ederiz.

+0

Bu yüzden bakıldığında, ud.getAddresses() öğesini çağırdığımda veritabanını sorguluyor mu? – KyelJmD

3

Sınıfların tüm temel özellikleri hemen yüklenir, bayt kodu geliştirmeleri kullanmadığınız sürece tembel olamazlar. Koleksiyonunuz gibi sadece gerçek çağrılar tembel olabilir.

+0

Başka bir Sınıf nasıl? Bu tembel başlatma olarak kabul edilir? – KyelJmD

+0

* Evet *, MTO'ya gelirse. Ve belki * OTO'ya gelirse. –

+0

MTO ve OTO ne anlama geliyor? – KyelJmD

11

Ben JPA/Hibernate aynı sorunu karşılaştığı ve bu sorunu çözmek için 2 yolu vardır:

1/aşağıdaki gibi varsayılan olarak Lazy kapatma: Tabii

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

, Bu şekilde performans sorunu nedeniyle tavsiye edilmez, böylece ikinci yoldan gidebilirsiniz.

2/Sen yöntemin başında @Transactional koyabilirsiniz, bu oturumun kalması için yardımcı olabilir, ya da başka bir anlayış, aşağıdaki gibi Hazırda oturumun görevini pass:

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

Cevabım geç geldi, ama başkalarına yardım etmeyi umuyorum :)

+0

Teşekkürler, @Transactional benim için çalıştı –