我有一个问题是得到我想要的对象而没有所有的孩子关联 .
我有我的 class 网站
@Entity
@Table(name = "Sites")
public class Site {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Id_Site", unique = true, nullable = false)
private long Id_Site;
private String ...;
private boolean ...;
private long ...;
private Date ...;
private Date ...;
private String ...;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set sequences = new HashSet();
@ManyToOne
private ... ...;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set ... = new HashSet();
@ManyToOne
private ... ...;
public constructor...
public set..
public get..
so, I only need Site object without sequences Association
在我的序列表中我有
@Entity
@Table(name = "Sequences")
public class Sequence {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Id_Sequence", unique = true, nullable = false)
private long Id_Sequence;
private Date ....;
private Date ....;
private String ....;
private String ....;
private String ....;
private int ....;
private int ....;
private double ....;
private double ....;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set traceSequences = new HashSet();
@ManyToOne(cascade = CascadeType.ALL)
private Site site;
public constructor...
public set..
public get..
所以,当我使用FetchType.Lazy时,调用我的方法:
@Override
public Site findSiteByName(String Name_Site) {
List sites = entityManager.createQuery("SELECT s FROM Site s").getResultList();
for (Site item : sites) {
if (item.getNom_Site().equals(Name_Site)) {
return item;
}
}
return null;
}
我收到这个错误:
未能懒惰地初始化角色集合:xxx.xxx.xxx.xxx.xxx.site.Site.sequences,无法初始化代理 - 没有会话
当我使用FetchType.EAGER时,我得到了Site对象,但我也获得了所有序列对象,以及其他关联的所有对象(我知道这是正常的)
请,有人知道为什么懒惰注释不起作用,以及如何解决这个问题
6 回答
正如上面其他SE成员所述,您收到此错误是因为会话已经关闭 .
如果要加载特定对象,则可以使用
Hibernate.initialize
方法 . 它将执行一个额外的查询来获取相关实体的数据 .因此,根据需要,与
Eager
加载相比,不会一直执行当jpa在会话关闭后尝试获取数据时,会发生这些延迟错误 .
但是使用eager会影响包含该实体的所有查询 .
尝试在查询中使用连接提取而不是急切 .
在代码中的某个地方,您调用
Site.GetSequences()
,可能在视图中或代码的另一部分中进行迭代 . 它看起来不像您提供的代码片段正在生成异常 .我尝试使用未加载到您的实体的集合,代码会抛出您提到的异常 .
要解决此问题,请通过在查询中更改提取到 EAGER 或使用 JOIN FETCH 来确定使用
sequences
的位置并在使用之前加载它们 .错误发生因为你尝试执行getSequences(),但因为是懒惰而会话是alredy关闭hibernate rais错误 . 为了避免这个错误,请在查询方法“内部”会话中读取sequencese,如下所示:
这是一个懒惰的加载,你只需要它就可以阅读内容!
我正在开发一个项目,旨在解决使用ModelMapper将实体映射到DTO时常见的JPA问题 . 该问题已在该项目中得到解决 . 项目链接:JPA Model Mapper
在这种情况下,我相信我们只想为所有延迟加载实体获取null . 对于这个问题,可以通过使用de JPA Model Mapper将实体映射到DTO来完成 .
我已在这个问题上回答了同样的问题:How to solve the LazyInitializationException when using JPA and Hibernate
返回一个hibernate托管实体(或一组hibernate托管实体)很可能会导致这类问题,除非你对返回的内容以及会话可用时hibernate填充的内容非常谨慎 .
我想说创建一个DTO(或DTO的集合)并按照你喜欢的方式填充它的字段 . 有许多实体到DTO转换框架;我的收藏是ModelMapper .
我也倾向于同意其他与FetchType一起使用的建议,但由于DTO由我们填充,我们知道我们填充的是什么,而不是基于注释由hibernate填充的实体关系 .
如果您在DTO中需要某些内容,您只需询问该实体,并且由于会话将在该时间点可用,您可以填充您认为在UI上需要的任何字段 .
我不想将这个主题劫持到DTO和实体,但我就是这样做的 .