我有两个实体,一个实体“电影”和一个实体“剪辑” 每个片段属于一个电影,电影可以有多个片段。
我的代码如下:
Movie.java
@OneToMany(mappedBy = "movie", targetEntity = Clip.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Clip> clips = new HashSet<Clip>();
Clip.java
@ManyToOne
@JoinColumn(name="movie_id")
private Movie movie;
正在生成表格,每个Clip都有一个列“movie_id”但这会导致我的应用程序在我请求数据时以无限循环结束
@Path("/{id:[0-9][0-9]*}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Movie lookupMovieById(@PathParam("id") long id) {
return em.find(Movie.class, id);
}
result:
{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"MGS Walkthrough P1","keywords":null,"movie":{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"MGS Walkthrough P1","keywords":null,"movie":{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"M...
当我请求剪辑时,结果相同。
当我将其更改为@ManyToMany关系时,不会有任何类似的问题,但这不是我需要的。你能帮助我吗?将fetchType设置为Lazy不起作用。
编辑:我正在使用当前的JBoss开发工作室
编辑:
通过阅读本文,我“解决了”这个问题:
http://blog.jonasbandi.net/2009/02/help-needed-mapping-bidirectional-list.html
“要将双向一个映射到多个,一对多一侧作为拥有方,您必须删除mappedBy元素并将多个@JoinColumn设置为可插入且可更新为false。此解决方案是显然没有优化,会产生一些额外的UPDATE语句。“
当我申请电影时,我得到以下答案:
{“id”:1,“version”:1,“name”:“MGS Walkthrough”,“filename”:“video.mp4”,“movieCategories”:[{“id”:1,“version” :1,“名称”:“演练”}],“剪辑”:[],“说明”:“预告片zu mgs4”}
条目“剪辑”仍然出现。这仍然是错误的解决方案,还是我必须忍受这个?
答案 0 :(得分:15)
我遇到了完全相同的问题。我尝试了引用段落中的解决方案,它对我不起作用。
我所做的是在Clip类中为getMovie()返回null,然后无限循环问题就消失了。以JSON格式返回的数据看起来像{“movieId”:1 ... clips:[“clipId”:1,“movie”:“null”,..]}。
如果您还想在JSON中进一步删除movie属性,请将类级注释添加到Clip类 @JsonSerialize(包括= JsonSerialize.Inclusion.NON_NULL)
Jackson feature: prevent serialization of nulls, default values
更新: 我找到的更简单的方法是在Clip类中删除电影的getter。
答案 1 :(得分:7)
解决方案:
使用
实例化的第一个对象的 @JsonManagedReference
注释
@JsonBackReference
注释
Movie.java
@JsonManagedReference
@OneToMany(mappedBy = "movie", targetEntity = Clip.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Clip> clips = new HashSet<Clip>();
Clip.java
@JsonBackReference
@ManyToOne
@JoinColumn(name="movie_id")
private Movie movie;
答案 2 :(得分:2)
正如您所说“条目剪辑仍然显示”。
避免数据库响应中的关系数据将fetch = FetchType.EAGER
更改为fetch = FetchType.Lazy
。
答案 3 :(得分:1)
我建议只返回一个DTO对象,而不是返回一个Entity对象。您可以使用结果转换器直接从Hibernate查询/条件结果中获取一个。
答案 4 :(得分:1)
我遇到了这种情况的主要问题。
获取Movie时,系统将加载关系剪辑的列表,但是在CLip类中,您具有属性Movie,当拥有此属性的吸气剂时,系统将再次加载Movie。
data <- structure(list(pitch_1 = c("429721-CU", "114849-FC", "430599-FF",
"458567-FF", "435261-CU", "425629-CU"), pitch_2 = c("493247-SI",
"493247-SI", "493247-SI", "493247-SI", "493247-SI", "493247-SI"
), euclid_dist = c(2.53, 3.52, 3.49, 2.59, 3.1, 2.14), rank = c(15L,
6L, 14L, 27L, 8L, 17L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))
例如: 您得到电影01,该电影与剪辑01和剪辑02有关系,当系统加载电影01的数据时,它也通过您的getter方法获取剪辑01和剪辑02的数据。
但是在Clip类中,您还具有属性Movie和一个getter getMovie()。因此,当系统查找CLip 01的数据时,它也获得了与Movie相关的数据,在这种情况下为Movie 01 ...,而Movie 01将获得CLip 01的数据=>因此,这正是我们产生循环的原因>
因此针对这种情况的确切解决方案是 在Clip.java中删除Getter方法getMovie() 我们不需要使用此信息
答案 5 :(得分:0)
首先,让我向您展示为什么将fetch type设置为lazy并没有帮助。 当您尝试序列化pojo时,序列化程序(也许是jackson)会调用此pojo的每个getter,并将getter的返回值用作json数据中的属性。因此,它将显式调用getter,后者将调用hibernate来加载关联的实体(Clip的movie和Movie的clip)。 因此,您需要使用@JsonIgnoreProperties摆脱这个奇怪的无限循环,代码如下:
<?php
global $wp_query;
$author = $wp_query->get_queried_object();
// author id
$author_id = get_the_author_meta('ID');
// vars
$test = get_field('test', 'user_'. $author_id ); ?>
// None of these work
<?= ( $test )? '<h1>' . $test .'</h1>' : '';?>
<h1><?php echo $test; ?></h1>
// This works
<h1 class="page-title page-title__author"><?php echo $author->display_name; ?></h1>
那样,您会发现剪辑json对象中的嵌套电影在电影内部没有“剪辑”,并且电影中的嵌套剪辑也没有“电影”子代。
我想这是解决此问题的最佳方法,也是开发Java Web应用程序的最佳实践。
答案 6 :(得分:0)
基本上,JsonIgnore或JsonBackrefrencing将删除一端的链接。
要进行正确的链接以及正确的Json输出,请遵循以下代码片段:-
@Entity
@Table(name="Movie")
public class Movie{
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id")
@OneToMany(mappedBy="movie",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Set<Clip> clips = new HashSet<Clip>();
}
@Entity
@Table(name="Clip")
public class Clip{
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id")
@ManyToOne
@JoinColumn(name="movie_id")
@JsonIgnore
private Movie movie;
}
请参阅下面的链接以获取更多详细信息: https://www.toptal.com/javascript/bidirectional-relationship-in-json
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
答案 7 :(得分:-1)
Dino Tw说的简单方法:
从getMovie()
类中删除Clip
函数。
这将有助于您检索Clip
实体/表格中Movie
关联的每个movie_id
的{{1}}列表。
答案 8 :(得分:-3)
@Entity
@Table(name="Movie")
public class Movie implements Serializable{
@OneToMany(mappedBy="movie",targetEntity=Clip.class,cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
private Set<Clip> clips = new HashSet<Clip>();
}
@Entity
@Table(name="Clip")
public class Clip implements Serializable{
@ManyToOne
@JoinColumn(name="movie_id")
@JsonIgnore
private Movie movie;
}