FetchType.EAGER不提取对象

时间:2017-07-13 12:33:33

标签: java hibernate jpa

我的实体:

@Entity
@NoArgsConstructor
public class Company {

  @Id
  @Getter
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "agent_id")
  private Agent agent;

}

@Entity
@NoArgsConstructor
public class Agent {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Getter
  private Long id;

  @Column(unique=true)
  @Getter
  private String name;
}

和问题方法

@Transactional
public void update(Company entity) {
    Company existing = companyRepository.getOne(entity.getId());
    //System.out.println(existing.getAgent().getName());
    em.detach(existing);
    System.out.println(existing.getAgent()); // => org.hibernate.LazyInitializationException: could not initialize proxy - no Session
}

最后一行导致LazyInitializationException,如果我取消注释System.out.println(),一切正常。所以它看起来像FetchType.LAZY。我做错了什么?

1 个答案:

答案 0 :(得分:2)

使用 findOne()方法代替 getOne()

方法 findOne() - 内部调用实体manager.getReference(...)

getReference()的结果称它为返回的对象,它是一个代理而不是实际的实体对象类型。因此,当您退出update()方法时,您无法再调用代理。

我建议您阅读How does a JPA Proxy work and how to unproxy it with Hibernate

区别在于:

  

getOne() - 懒惰加载

     

findOne() - 不是