我对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
返回普通对象而不是代理对象?
答案 0 :(得分:0)
每次调用get
时,Hibernate都不会访问数据库。
所以,因为session.get(Product.class)
在会话中已经有了一个公司实例(虽然是代理)所以Hibernate只是初始化了那个代理(因此你看到的是sql)。
答案 1 :(得分:0)
首先 session.get永远不会返回代理对象它会从持久空间返回一个完全初始化的对象(如果它存在),否则它会命中数据库从那里获取对象并给它back else返回null。
正如java doc所说:
返回给定实体类的持久实例和给定标识符,如果没有这样的持久实例,则返回null。 (如果实例已与会话关联,则返回该实例。此方法永远不会返回未初始化的实例。)
有关详细信息,请访问“http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/Session.html#get(java.lang.Class,java.io.Serializable”链接。