Hibernate会话get方法返回代理对象

时间:2018-01-05 14:35:45

标签: java hibernate proxy

我对Hibernate会话get方法感到困惑。我的理解是get方法总是返回真实对象而不是代理对象(ref)。

但是在我的程序中,即使我使用get方法,我也会得到代理对象。

我的情景:

我有两张表productcompany

产品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返回普通对象而不是代理对象?

2 个答案:

答案 0 :(得分:0)

每次调用get时,Hibernate都不会访问数据库。

请参阅JavaDocs获取:If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.

所以,因为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”链接。