[英]Hibernate could not initialize proxy - no Session
My code retrieves all information related to the user: 我的代码检索与用户相关的所有信息:
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());
}
The ud.getAddresses()
simply returns a set of Address
es of the user. ud.getAddresses()
只返回用户的一组Address
es。
My question is: why does the ud
object still have its value (eg, name) even though the session is already closed? 我的问题是:为什么即使会话已经关闭,
ud
对象仍然具有其值(例如,名称)? getAddresses()
is an instance variable of the UserDetails
class. getAddresses()
是UserDetails
类的实例变量。 But why can't I retrieve its value but I can retrieve regular instance variables of the UserDetails
class? 但为什么我不能检索它的值,但我可以检索
UserDetails
类的常规实例变量?
ud.getAddresses()
is an @EmbeddedCollection
. ud.getAddresses()
是一个@EmbeddedCollection
。
I faced the same issue in JPA/Hibernate, and there are 2 ways to solve this issue: 我在JPA / Hibernate中遇到了同样的问题,有两种方法可以解决这个问题:
1/ Turn off the LAZY by default, as following: 1 /默认关闭LAZY,如下所示:
@Entity
@Proxy(lazy = false)
public class Project {
...
}
Of course, this way is not recommended because of the performance issue, so you can go to the second way. 当然,由于性能问题,不建议采用这种方式,因此您可以采用第二种方式。
2/ You can put @Transactional at the beginning of your method, it can help you to remain the session, or another understanding, it pass the duty of session to Hibernate, as following: 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());
}
My answer is late, but hope to help someone else :) 我的回答很晚,但希望能帮助别人:)
userAddress = ud.getAddresses();
session.getTransaction().commit();
for(Address addr: userAddress) {
The hibernate documentation for working with lazy associations clearly calls out this kind of access as an error. 用于处理惰性关联的hibernate文档明确地将这种访问称为错误。 You can interact with lazily associated objects only while the session is still open.
只有在会话仍处于打开状态时,您才能与延迟关联的对象进行交互。 That portion of the documentation also provides alternatives to access such lazily associated members of an object and we prefer to specify the fetch mode as JOIN in the criteria used, in our applications.
文档的这一部分还提供了访问对象的延迟关联成员的替代方法,我们更倾向于在我们的应用程序中将获取模式指定为使用标准中的JOIN。
All the primitive properties of the classes are loaded right away, they can't be lazy unless you're using bytecode enhancements. 类的所有原始属性都会立即加载,除非您使用字节码增强,否则它们不能延迟。 Only real associations like your collection can be lazy.
只有像你的收藏品这样真正的联想可能是懒惰的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.