Java 会话关闭后,如何禁用或阻止使用Hibernate代理?
因此,我现在正在开发一个RESTful API,它充当客户端和数据库之间的一个层,我目前正在使用Hibernate for ORM,几天来我一直在尝试找到问题的解决方案,到处搜索都没有用 我不能发布我正在使用的实际代码,因为它太大了,但是想象一下: 我有一个类Java 会话关闭后,如何禁用或阻止使用Hibernate代理?,java,hibernate,jdbc,Java,Hibernate,Jdbc,因此,我现在正在开发一个RESTful API,它充当客户端和数据库之间的一个层,我目前正在使用Hibernate for ORM,几天来我一直在尝试找到问题的解决方案,到处搜索都没有用 我不能发布我正在使用的实际代码,因为它太大了,但是想象一下: 我有一个类Employee映射为如下所示的Hibernate实体 @实体 公营雇员{ @身份证 整数id; 字符串名; 双薪; 弦乐部; @manytone(fetch=FetchType.LAZY) @JoinColumn(name=“公司id”)
Employee
映射为如下所示的Hibernate实体
@实体
公营雇员{
@身份证
整数id;
字符串名;
双薪;
弦乐部;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“公司id”)
公司;
//获得者/接受者
@凌驾
公共字符串toString(){
返回“雇员{”+
“id=”+id+
“,name=”“+name+”\“””+
“,salary=“+salary+
“,部门=”+部门+“\”+
“,company=“+公司+
'}';
}
}
还有另一个实体类Company
,如下所示:
Employee:
| id | name | salary | department | company_id |
|----|----------|--------|------------|------------|
| 1 | john doe | 3000 | Finance | 1 |
| 2 | mary sue | 3300 | HR | 1 |
Company:
| id | name | address |
|----|------|------------|
| 1 | ACME | St. Sesame |
Employee{id=1,name='john doe',salary=3000.0,department='Finance',company=Company{id=1,name=null,address=null,employees=null}}
@实体
公营公司{
@身份证
整数id;
字符串名;
字符串地址;
@OneToMany(mappedBy=“company”,fetch=FetchType.LAZY)
列出员工名单;
//接球手和接球手
@凌驾
公共字符串toString(){
返回“公司{”+
“id=”+id+
“,name=”“+name+”\“””+
“,地址=”“+地址+”\“””+
“,employees=“+雇员+
'}';
}
}
数据库如下所示:
Employee:
| id | name | salary | department | company_id |
|----|----------|--------|------------|------------|
| 1 | john doe | 3000 | Finance | 1 |
| 2 | mary sue | 3300 | HR | 1 |
Company:
| id | name | address |
|----|------|------------|
| 1 | ACME | St. Sesame |
Employee{id=1,name='john doe',salary=3000.0,department='Finance',company=Company{id=1,name=null,address=null,employees=null}}
现在让我们假设我想从某个员工那里获取数据,如果我以后需要公司数据,我只需要员工数据+公司ID(并且只有ID)作为参考。它看起来像这样:
Employee:
| id | name | salary | department | company_id |
|----|----------|--------|------------|------------|
| 1 | john doe | 3000 | Finance | 1 |
| 2 | mary sue | 3300 | HR | 1 |
Company:
| id | name | address |
|----|------|------------|
| 1 | ACME | St. Sesame |
Employee{id=1,name='john doe',salary=3000.0,department='Finance',company=Company{id=1,name=null,address=null,employees=null}}
Session Session=SessionManager.openSession();
Employee emp=session.get(Employee.class,1);
session.close();
现在我想显示员工数据
System.out.println(emp);
这里预期的输出(或者至少是我预期的)是这样的:
Employee:
| id | name | salary | department | company_id |
|----|----------|--------|------------|------------|
| 1 | john doe | 3000 | Finance | 1 |
| 2 | mary sue | 3300 | HR | 1 |
Company:
| id | name | address |
|----|------|------------|
| 1 | ACME | St. Sesame |
Employee{id=1,name='john doe',salary=3000.0,department='Finance',company=Company{id=1,name=null,address=null,employees=null}}
这很简单,问题是它会抛出LazyInitializationException,因为Hibernate在调用Employee的toString()
时试图使用代理对象获取de Company数据,但会话已经关闭
问题是,如果我关闭了会话而没有获取更多的数据,那么就是这样,不再需要数据,休眠!如果我打开一个会话,我将获取我需要的所有数据,并且只获取我需要的数据,关闭会话后,这意味着我不再需要任何数据,谢谢hibernate,但hibernate的代理对象即使在会话关闭后仍保持活动状态
我搜索了整个网络,甚至在StackOverflow上,这里也有一些所谓的“解决方案”或“变通方法”,如:
- 为什么不将HQL与构造函数一起使用?
- 您可以将HQL与构造函数一起使用,并为需要在查询中访问的每个数据库表创建实体
- 然后使用本机查询,当您不需要该列数据时,可以将
NULL作为columnName
- 为什么不使用“在视图上打开会话”模式使会话保持打开状态?
- session.detach()?
- 无状态会话?
- 为什么不使用DTO?
- 这个问题围绕着如何“取消专利”