如何使用FetchType.LAZY加载OneToMany Collections数据作为响应?

时间:2015-05-26 13:11:41

标签: spring hibernate spring-data-jpa jhipster

我创建了一个示例 jHipster 示例应用(网址:http://jhipster.github.io/creating_an_app.html),使用实体子生成器我创建了一个事件实体,其中 EventImages , EventTickets EventQuestions 的关系> OneToMany {3}})事件我无法在响应中找到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 Collections数据,我得到的响应是 null ,用于EventImage,EventTicket和EventQuestions,如下所示。

[ {
"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
 } ]

然后我发现我需要在父/子关系上使用@JsonManagedReference和@JsonBackReference,但需要使用fetch = Fetch.EAGAR(当我设置 FetchType.LAZY 时,我想要加载OneToMany集合默认情况下,作为调用Event实体的时间。)

我使用@JsonManagedReference时的事件实体

@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 */
}

如何加载OneToMany集合懒惰,即事件实体请求时响应的EventImages,EventTickets和EventQuestions,即http://127.0.0.1:8080/api/events REST调用。

由于

1 个答案:

答案 0 :(得分:0)

我实际上并不理解你的问题,但我试着解释JPA是如何运作的。

正如您所提到的,使用JPA可以加载LAZILY或EAGERLY。

  • LAZY表示您不从头开始加载集合。只有在您访问集合时才会加载该集合(这仅适用于加载或附加实体的同一事务)。

  • EAGER表示从一开始就加载集合(因为实体本身已加载)。

因此,如果您想通过REST服务提供集合,那么您必须在事务期间加载集合。

这可以通过以下几种方式完成:

  • 一种方法是将集合的FetchType定义为EAGER
  • 另一种方法是LAZY加载集合,加载实体后,访问集合(例如通过调用size() - &gt; event.getEventImages()。size();)
  • 另一种方法是使用JPQL-Query加载实体和集合(SELECT e FROM Event JOIN FETCH e.eventImages ...)
  • 根据您使用的JPA实现,还有更多方法可以实现此目的

所以,如果我理解你的问题,那么你可以使用

注释你的Spring-Data-DAO-Find-Method

@Query("SELECT e FROM Event JOIN FETCH e.eventTickets, JOIN FETCH e.eventImages, JOIN FETCH e.eventQuestions")