当前位置: 首页 > 知识库问答 >
问题:

如何使用FetchType加载OneToMany Collections数据作为响应。懒惰?

齐坚成
2023-03-14

我创建了一个jHipster示例应用程序(url:http://jhipster.github.io/creating_an_app.html),使用实体子生成器,我创建了一个事件实体,当我检索所有时,该实体与EventImages、EventTickets和EventQuestions具有一个域关系(应用程序在本地计算机上运行,api url:http://127.0.0.1:8080/api/events)事件我在响应中找不到EventImages、EventTickets和EventQuestions数据。

事件实体

@Entity
@Table(name = "JHI_EVENT")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Event implements Serializable {

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

/* other fields */

@OneToMany(mappedBy = "event")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonIgnore
private Set<EventTicket> eventTickets = new HashSet<>();

@OneToMany(mappedBy = "event")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonIgnore
private Set<EventImage> eventImages = new HashSet<>();

@OneToMany(mappedBy = "event")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonIgnore
private Set<EventQuestion> eventQuestions = new HashSet<>();

/* getter and setters */

}

EventImages实体

@Entity
@Table(name = "JHI_EVENTIMAGE")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class EventImage implements Serializable {

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

@Column(name = "image_url")
private String imageUrl;

@ManyToOne
private Event event;

 /* getters and setters */
}

类似地,EventTickets和EventQuestions实体。

经过一些研究,我发现我需要删除@JsonIgnore注释以使用延迟获取加载OneToMany集合数据,对于EventImage、EventTicket和EventQuestions,我得到的响应为null,如下所示。

[ {
"id": 1,
"title": "First Event",
"eventVenue": "xyz",
"startDate": "2015-05-28T10:10:00Z",
"endDate": "2015-06-20T10:10:00Z",
"eventTickets": null,
"eventImages": null,
"eventQuestions": null
 } ]

然后我发现我需要在父/子关系上使用@JsonManagedResources和@JsonBackResources,但需要使用fetch=Fetch。EAGAR(当我设置FetchType时,我想加载OneTo众多集合。LAZY是默认的,作为调用事件实体时)。

当我使用@JsonManaged参考时的事件实体

@Entity
@Table(name = "JHI_EVENT")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Event implements Serializable {

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

/* other fields */

@OneToMany(mappedBy = "event", fetch = FetchType.EAGER)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonManagedReference
private Set<EventTicket> eventTickets = new HashSet<>();

@OneToMany(mappedBy = "event", fetch = FetchType.EAGER)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonManagedReference
private Set<EventImage> eventImages = new HashSet<>();

@OneToMany(mappedBy = "event", fetch = FetchType.EAGER)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonManagedReference
private Set<EventQuestion> eventQuestions = new HashSet<>();

/* getter and setters */

}

使用@JsonBackReference时的EventImage实体

@Entity
@Table(name = "JHI_EVENTIMAGE")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class EventImage implements Serializable {

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

@Column(name = "image_url")
private String imageUrl;

@ManyToOne
@JsonBackReference
private Event event;

 /* getters and setters */
}

如何在请求事件实体(即http://127.0.0.1:8080/api/events进行Rest通话。

谢啦

共有1个答案

林浩漫
2023-03-14

我实际上不明白你的问题,但我试图解释JPA是如何工作的。

正如您所提到的,使用JPA您可以懒洋洋地加载集合,也可以急切地加载集合。

>

  • 懒惰意味着不从一开始就加载集合。只有在访问集合时才会加载集合(这仅适用于加载或附加实体的同一事务)。

    渴望意味着从一开始就加载集合(就像加载实体本身一样)。

    因此,如果希望通过REST服务提供集合,则必须在事务期间加载集合。

    这可以通过以下几种方式实现:

    • 一种方法是将集合的FetchType定义为EAGER

    所以,如果我理解了你的问题的正确性,那么你可以用

    查询(“从事件中选择e JOIN FETCH e.eventTickets、JOIN FETCH e.eventImages、JOIN FETCH e.eventQuestions”)

  •  类似资料:
    • 我有模型类别。它可能有父类别和子类别列表。我写这个问题是因为找不到实体和自己相关的情况。 我试图这样实现它: 我保存实体,如: 我希望看到这样的情况: 但是在子模型中,我有递归循环。如何防止它? 是的,我也使用了@JsonIgnore。但是我不确定这是不是一个好的做法。但是如果我有一个案例,当我需要一个类别时,我真的需要将它发送给父母的UI。@JsonIgnore可以产生这个吗?

    • 我试图在primefaces数据表设置中实现延迟加载。目前,在没有延迟加载实现的情况下,这是可行的,但是在实现延迟加载后,我在datatable中没有得到任何数据。但是,我可以在我的LoadData方法中打印我的列表,以验证数据是否正在加载到我的列表中,但一旦返回我的LazyModel并尝试加载datatable,似乎就会出现问题。这可能只是我忽略的一些简单的事情。非常感谢您的帮助! 这是我的屏幕

    • 问题内容: 我的要求是使用HTTP Servlet将PDF数据响应到移动客户端(iPhone)。 我是按照以下方式完成的,但是我没有在客户端获得预期的输出。 我遵循的方法正确吗?请指教。 谢谢。 问题答案: 您必须使用ServletOutputStream及其write()方法将字节写入response。

    • 数据是通过懒加载获取的,default-expanded-keys属性值需要从顶层根节点到当前选中节点的key路径,现在回显的时候只能得到当前选中节点的key,这样该如何回显呢? 想要的效果是:编辑回显时,展开树形控件选中的节点是默认选中的状态

    • react项目为了做性能优化减小包体积在项目中用了大量的React.lazy加载组件进行代码分割,效果也挺明显,包大小从1.4M缩小到110KB但是到生产后监控到通过React.Lazy这种方式加载组件会有失败的场景(走到了代码的catch)。请问下这种场景页面是不是会报错白屏(复现不出来不知道现象是怎么样的) 请问各位大佬这种情况该怎么处理啊?添加重试功能? 还是像官方的处理一样添加ErrorB