Java JPA OneToMany,在控制台或webapp中打印时如何忽略字段MANYTONE
我有两个表格:流派(流派id,流派名称)和电影(电影id,电影名称,电影分数,流派id)。流派id来自引用流派中流派id的电影Java JPA OneToMany,在控制台或webapp中打印时如何忽略字段MANYTONE,java,spring-boot,jpa,Java,Spring Boot,Jpa,我有两个表格:流派(流派id,流派名称)和电影(电影id,电影名称,电影分数,流派id)。流派id来自引用流派中流派id的电影 @Entity @Table(name = "genres", schema = "test") public class Genre { @Id @Column(name = "genre_id") private int id; @Column(name = "genre_name") private String name; @OneToMany(mappedB
@Entity
@Table(name = "genres", schema = "test")
public class Genre {
@Id
@Column(name = "genre_id")
private int id;
@Column(name = "genre_name")
private String name;
@OneToMany(mappedBy = "genre", fetch = FetchType.LAZY)
private List<Movie> movies = new ArrayList<>();
}
当我尝试使用以下代码在控制台中打印时:
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();
Genre genre = em.find(Genre.class, 1);
System.out.println(genre);
}
在线程“main”java.lang.StackOverflower中接收异常
只有删除电影类字段“流派”中的toString()才能修复它。但有可能避免吗?
spring启动应用程序也存在同样的问题
@RestController
public class GenreController {
@Autowired
private GenreService genreService;
@RequestMapping("/test/{id}")
public List<Genre> getGenreInfo(@PathVariable int id){
return genreService.getGenreFilms(id);
}
}
告诉我哪里做错了,如何修复或用谷歌搜索这个问题?只是不按localhost:8080/genre/id打印此对象?制作一些特别的印刷品或什么?当你尝试
toString
你的类型
实体时,你似乎有一个无限的递归。代码首先按id加载流派实体,然后调用Genre.toString()
。因为您与Movie
s有@OneToMany
关系,所以它延迟加载列表
,然后为与该类型相关的每部电影调用Movie.toString()
。然后,对于每一部电影,你都有一个与类型相关的@manytone
。问题就在这里。对于列表中的每部电影,它将再次调用Genre.toString()
可能的解决方案
Genre.toString()中包含电影列表
@JsonBackReference
添加到Movie
中的@manytone
关系中,这样Jackson在映射到Json时将忽略它
Movie
属性即可李>
希望这能有所帮助。当您尝试
toString
您的流派
实体时,似乎有一个无限的递归。代码首先按id加载流派实体,然后调用Genre.toString()
。因为您与Movie
s有@OneToMany
关系,所以它延迟加载列表
,然后为与该类型相关的每部电影调用Movie.toString()
。然后,对于每一部电影,你都有一个与类型相关的@manytone
。问题就在这里。对于列表中的每部电影,它将再次调用Genre.toString()
可能的解决方案
Genre.toString()中包含电影列表
@JsonBackReference
添加到Movie
中的@manytone
关系中,这样Jackson在映射到Json时将忽略它
Movie
属性即可李>
希望这有帮助
@RestController
public class GenreController {
@Autowired
private GenreService genreService;
@RequestMapping("/test/{id}")
public List<Genre> getGenreInfo(@PathVariable int id){
return genreService.getGenreFilms(id);
}
}
@Service
public class GenreService {
public List<Genre> getGenreFilms(int id){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();
List<Genre> genres = new ArrayList<>();
Genre genre = em.find(Genre.class, id);
genres.add(genre);
return genres;
}
}
22:15:37.154 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad -
Resolving associations for [com.company.Genre#1]
22:15:37.164 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done
materializing entity [com.company.Genre#1]
22:15:37.164 [main] DEBUG
org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl -
HHH000387: ResultSet's statement was not registered
22:15:37.165 [main] DEBUG
org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done
entity load : com.company.Genre#1
22:15:37.165 [main] DEBUG
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl -
Initiating JDBC connection release from afterTransaction
22:15:37.167 [main] DEBUG org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer
- Loading collection: [com.company.Genre.movies#1]
22:15:37.167 [main] DEBUG org.hibernate.SQL - select movies0_.genre_id as
genre_id4_1_0_, movies0_.movie_id as movie_id1_1_0_, movies0_.movie_id as
movie_id1_1_1_, movies0_.genre_id as genre_id4_1_1_, movies0_.movie_name as
movie_na2_1_1_, movies0_.movie_score as movie_sc3_1_1_ from test.movies
movies0_ where movies0_.genre_id=?
Hibernate: select movies0_.genre_id as genre_id4_1_0_, movies0_.movie_id as
movie_id1_1_0_, movies0_.movie_id as movie_id1_1_1_, movies0_.genre_id as
genre_id4_1_1_, movies0_.movie_name as movie_na2_1_1_, movies0_.movie_score
as movie_sc3_1_1_ from test.movies movies0_ where movies0_.genre_id=?
22:15:37.168 [main] DEBUG
org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl -
Preparing collection intializer : [com.company.Genre.movies#1]
22:15:37.170 [main] DEBUG
org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl -
Starting ResultSet row #0
22:15:37.171 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerIm
pl - Found row of collection: [com.company.Genre.movies#1]
22:15:37.171 [main] DEBUG
org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl -
Starting ResultSet row #1
22:15:37.172 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerIm
pl - Found row of collection: [com.company.Genre.movies#1]
22:15:37.172 [main] DEBUG
org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl -
Starting ResultSet row #2
22:15:37.172 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerIm
pl - Found row of collection: [com.company.Genre.movies#1]
22:15:37.172 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad -
Resolving associations for [com.company.Movie#1]
22:15:37.172 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done
materializing entity [com.company.Movie#1]
22:15:37.173 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad -
Resolving associations for [com.company.Movie#2]
22:15:37.173 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done
materializing entity [com.company.Movie#2]
22:15:37.173 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad -
Resolving associations for [com.company.Movie#3]
22:15:37.173 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done
materializing entity [com.company.Movie#3]
22:15:37.173 [main] DEBUG
org.hibernate.engine.loading.internal.CollectionLoadContext - 1 collections
were found in result set for role: com.company.Genre.movies
22:15:37.173 [main] DEBUG
org.hibernate.engine.loading.internal.CollectionLoadContext - Collection
fully initialized: [com.company.Genre.movies#1]
22:15:37.173 [main] DEBUG
org.hibernate.engine.loading.internal.CollectionLoadContext - 1 collections
initialized for role: com.company.Genre.movies
22:15:37.173 [main] DEBUG
org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl -
HHH000387: ResultSet's statement was not registered
22:15:37.173 [main] DEBUG org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer
- Done loading collection
Exception in thread "main" java.lang.StackOverflowError