JPA。 FetchType.Lazy引起了奇怪的行为@ManyToOne

时间:2016-06-27 13:27:34

标签: hibernate jpa many-to-one jpa-2.1

我正在尝试提高使用JPA的项目的性能。

我正在使用JPA 2.1和Hibernate 5.0.1实现。

我将ManyToOne关系的FetchType更改为Lazy,所以事情就会爆发。

当我尝试查找子对象的所有记录时:最后一条记录带有所有空字段并带有handler = JavassistLazyInitializer。这种奇怪的行为会影响使用此对象的字段(如h:OneSelectMenu)。

如果我将FetchType.Lazy删除正常。

一些印刷品:

Debug child list 2

FetchType.Lazy

第二次打印的代码(FetchType.Lazy):

public class Usuario implements Serializable {
  private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id_Usuario")
private Integer idUsuario;

// Fields ...

@JoinColumn(name = "Id_Tipo_Logradouro", referencedColumnName = "Id_Tipo_Logradouro", nullable = true)
@ManyToOne(optional = true, fetch = FetchType.LAZY)
private TipoLogradouro tipoLogradouro;

@JoinColumn(name = "Id_Tipo_Usuario", referencedColumnName = "Id_Tipo_Usuario")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private TipoUsuario tipoUsuario;

@JoinColumn(name = "Id_Supervisor", referencedColumnName = "Id_Usuario")
@ManyToOne(optional = true, fetch = FetchType.LAZY)
private Usuario supervisor;

// Contructor, Getters Setters etc ...

}

public class TipoUsuario implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "Id_Tipo_Usuario")
private String idTipoUsuario;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 20)
@Column(name = "Descricao")
private String descricao;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "Possui_Supervisor")
private String possuiSupervisor;

@Size(max = 1)
@Column(name = "Possui_Meta")
private String possuiMeta;

@Size(max = 1)
@Column(name = "Recebe_Alerta")
private String recebeAlerta;

@Transient
private List<Usuario> usuarioList = new ArrayList<>();

//Contructor, Getters Setters etc ...

1 个答案:

答案 0 :(得分:1)

<强>为什么

使用延迟加载,您指示EntityManager除非有人要求,否则不会获取这些详细信息。因此,如果在您的交易中,您没有要求提取property,那么您将只获得它的代理。但是,如果您要求代理处理与该属性相关的任何内容,e.x.的大小,EntityManager将为您提供按需的信息。

看起来您正在使用JSF进行查看,现在在这种情况下,在您的模型要求提供这些详细信息之前,实体管理器已经完成其工作因此不知道它必须再次从DB获取这些详细信息。请记住,代理是序列化的,因此对于您的视图,您的集合看起来像是空/空。

如何解决此问题

正确答案取决于您的使用情况。

如果您当前延迟加载的信息始终需要显示在前端,那么您无法使其延迟加载。

否则,如果您只有在有人点击下拉菜单时才需要显示它,那么您可以根据带有Fetch Joins的JPA查询填充这些值。

否则,如果你有EJB,你可以考虑延长你的EntityManager

每个选项都有很多详细信息,但您可以查看Adam Bien的这个blog post,了解上述所有选项的详细信息等等!

更新1 :请查看此answer,了解如何在服务器端加载延迟加载的属性。