我有以下实体(连接到db):
@Entity
public class Campaign {
// ...
@OneToMany(fetch = FetchType.LAZY)
private List<Subscriber> subscribers;
}
@Entity
public class Subscriber {
// ...
}
我想获取广告系列但忽略订阅者。在我的控制器中,我jsonify广告系列,但会触发错误,因为它会尝试延迟加载订阅者。在这种情况下,我不希望它延迟加载订阅者,只打印出广告系列(在其他情况下我想要打印出来)。
我尝试在hql查询中选择特定字段,但返回的数组不是对象。
答案 0 :(得分:2)
正如@Gimbly所说,我正在错误地查看问题,需要查看序列化对象的内容。我从以下帖子得到了答案:
答案 1 :(得分:1)
只有当某人执行方法getSubscribers()
(实际上是代理列表)时,才会触发订阅者数据库查询。
因此,如果subscribers
字段为空,则永远不会触发查询。
也就是说,快速(但不是那么干净)的解决方案是创建一个方法,将null
设置为此字段,但不改变数据库,如下所示:
@PersistentContext
private EntityManager em;
/* ... */
private void detachCampaigns(List<Campaign> campaigns){
for(Campaign c: campaigns){
em.detach(c); // Exclude from JPA context
c.setSubscribers(null); // inhibits lazy proxy list
}
}
方法detachCampaigns()
将:
null
覆盖代理对象,因此如果您的代码尝试调用getSubscriers()
,则无法访问数据库以避免出现问题。在此之后,您只需在json化广告系列之前调用此方法。
答案 2 :(得分:0)
主要问题是您要序列化实体而不是只读投影。
在后一种情况下,您可以轻松定义结果中要包含的字段,而不必处理任何延迟加载问题。
仅在需要更改状态时才使用实体。
对于创建投影,您可以使用基本定义界面的Spring Data JPA way,框架将处理其他界面。
如果您无法使用Spring Data JPA,那么您可以将投影定义为类,并通过JPQL / HQL / Criteria API甚至本机查询获取必要的属性。