【发布时间】:2018-01-05 14:35:45
【问题描述】:
我对 Hibernate 会话 get 方法感到困惑。我的理解是get 方法总是返回真实对象而不是代理对象(ref)。
但在我的程序中,即使我使用 get 方法,我也会得到代理对象。
我的场景:
我有两张桌子product 和company。
产品 JPA:
@Entity
@Table(name = "PRODUCT")
public class Product {
@Id
@Column(name = "prd_id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "price")
private int price;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cmp_id")
private Company company;
}
公司 JPA:
@Entity
@Table(name = "COMPANY")
public class Company {
@Id
@Column(name = "cmp_id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Column(name = "revenue")
private int revenue;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
private List<Product> products;
}
在我的主要方法中,我有以下代码:
Product product = (Product) session.get(Product.class, 1); // this product has cmp_id 1
System.out.println("Got product");
Company company = (Company) session.get(Company.class, 1);
System.out.println(company instanceof HibernateProxy); // this returns true
我知道由于延迟加载,Hibernate 将公司 1 作为来自Product product = (Product) session.get(Product.class, 1); 的代理对象。
但我期待(Company) session.get(Company.class, 1); 返回正常对象。
从日志中,我看到 hibernate 确实命中了数据库并获得了 Company 对象的完整数据。这使得它更加混乱,如果 hibernate 拥有所有数据,为什么仍然返回代理对象?
我的理解不正确吗?如何确保会话get 返回普通对象而不是代理对象?
【问题讨论】:
-
您提供的参考文献的一位评论员 (Lluis) 指出:“Javadoc 说:返回具有给定标识符的给定实体类的持久实例,如果没有这样的持久实例,则返回 null。 (如果实例已经与会话关联,则返回该实例。此方法永远不会返回未初始化的实例。)它只会访问数据库一次。具有相同 id 的后续调用将返回缓存的实例。"