15

私のコードは、ユーザーに関連するすべての情報を取得します。

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

単にユーザーのesのセットud.getAddresses()を返します。Address

私の質問は、セッションがすでに閉じられているのに、なぜudオブジェクトにその値(名前など)が残っているのですか?クラスgetAddresses()のインスタンス変数です。UserDetailsしかし、なぜその値を取得できないのに、UserDetailsクラスの通常のインスタンス変数を取得できるのでしょうか。

ud.getAddresses()です@EmbeddedCollection

4

3 に答える 3

20

JPA / Hibernateでも同じ問題に直面しましたが、この問題を解決するには2つの方法があります。

1 /次のように、デフォルトでLAZYをオフにします。

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

もちろん、パフォーマンスの問題があるため、この方法はお勧めしません。そのため、2番目の方法に進むことができます。

2 /メソッドの先頭に@Transactionalを置くことができます。これは、セッションを継続するのに役立ちます。または、次のように、セッションの義務をHibernateに渡します。

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

私の答えは遅れていますが、他の誰かを助けたいと思っています:)

于 2016-08-03T02:09:06.573 に答える
17
userAddress = ud.getAddresses();
session.getTransaction().commit();
for(Address addr: userAddress) {

怠惰なアソシエーションを操作するための休止状態のドキュメントは、この種のアクセスをエラーとして明確に示しています。セッションがまだ開いている間のみ、遅延して関連付けられたオブジェクトを操作できます。ドキュメントのその部分は、オブジェクトのそのような怠惰に関連付けられたメンバーにアクセスするための代替手段も提供します。アプリケーションでは、使用される基準でフェッチモードをJOINとして指定することをお勧めします。

于 2012-11-21T11:45:24.787 に答える
4

クラスのすべてのプリミティブプロパティはすぐに読み込まれます。バイトコード拡張機能を使用していない限り、それらを遅延させることはできません。あなたのコレクションのような本当の連想だけが怠惰になることができます。

于 2012-11-21T11:59:15.393 に答える