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

JPA OneToMany,在控制台或webapp中打印时如何忽略字段ManyToMany

松兴邦
2023-03-14

我有两个表:流派(genre\u id,genre\u name)和电影(movie\u id,movie\u name,movie\u score,genre\u id)。电影中的genre\u id\u fk引用了genres中的genre\u 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(mappedBy = "genre", fetch = FetchType.LAZY)
private List<Movie> movies = new ArrayList<>();
}

和第二个电影实体

@Entity
@Table(name = "movies", schema = "test")
public class Movie {

@Id
@GeneratedValue
@Column(name = "movie_id")
private int id;
@Column(name = "movie_name")
private String name;
@Column(name = "movie_score")
private double score;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "genre_id")
private Genre genre;
}

当我尝试使用以下代码在控制台中打印它时:

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.StackOverflow Error只有从电影类字段“genres”中的toString()中删除才能修复它。但是有可能避免它吗?Spring启动应用程序也有同样的问题

@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;
}
}

收到这样的问题:[{“id”:1,“name”:“Thriller”,“movies”:[{“id”:1,“name”:“Any,你还好吗?”,“score”:5.45,“流派”:{“id”:1,“name”:“Thriller”,“movies”:[{“id”:1,“name”:“Any,you ok?”,“score”:5.45,“流派”:{“id”:1,“name”:“Thriller”,“movies”:[{“id”:1,“name”:“Any,you ok?”,“得分”:5.45,“流派”:。。。。除了sof之外,还有无穷大。我可以通过在toString()方法中忽略字段来修复控制台。但是如何在webapplication中解决这个问题呢?

控制台打印时,在此Hibernate调试日志

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

告诉我哪里做错了,如何修复或用谷歌搜索这个问题?只是不按本地主机打印此对象:8080/流派/id?做一些特别的印刷品还是什么?

共有1个答案

壤驷文华
2023-03-14

当你尝试去串你的类型实体时,你似乎有一个无限的递归。代码首先按id加载流派实体,然后调用流派。toString()。因为您与电影有关系,所以它会延迟加载列表,然后调用电影。toString()适用于与该类型相关的每部电影。那么,对于每一部电影,你都与流派有着千丝万缕的联系。这就是问题所在。它将再次调用流派。列表中每部电影的toString()。

  1. 如果您只想在控制台中简单地打印它,请不要在Genre.toString()
  2. 中包含电影列表
  3. 如果您使用的是Jackson,请在Movie中将@JsonBack参考添加到您的@ManyToOne关系中,这样Jackson在映射到Json时会忽略它注释留档在这里
  4. 如果使用DTO,请不要在您的DTO中包含Movie属性。

希望这有帮助。

 类似资料:
  • 我试图使用TDD(测试驱动开发)与。当我使用时,不会到控制台。 我正在使用来运行它。 似乎说默认情况下它应该工作:http://pytest.org/latest/capture.html 但是: 没有任何东西被打印到我的标准输出控制台(只是正常的进度和多少测试通过/失败)。 我正在测试的脚本包含打印: 在模块中,默认情况下打印所有内容,这正是我所需要的。但是,出于其他原因,我希望使用。 有人知道

  • 问题内容: 我一直在寻找其他语言的用法,但发现必须使用特殊字符\b删除最后一个字符。 对于多次调用console.log()的node.js,这不起作用。 如果我写一个日志: 我得到结果:abd 但是如果我写: 我得到结果: abc d 我的目标是打印一条等待消息,例如: 等待 等待。 等待中.. 等待中… 然后再次: 等待 等待。 等等 都在同一行。 问题答案: 有以下功能可用: 可以提供参数

  • 问题内容: 如何打印(在控制台),,等这个结构中Golang的? 问题答案: 要在结构中打印字段名称: 从包装中: 打印结构时,加号()添加字段名称 假设您有一个Project的实例(在’ ‘中) 文章JSON和Go将提供有关如何从JSON结构中检索值的更多详细信息。 此“按示例进行搜索”页面提供了另一种技术: 那会打印: 如果没有任何实例,则需要 使用反射 来显示给定结构的字段名称,如本例所示。

  • 如何在Golang中打印(在控制台中)该结构的、、等?

  • 问题语句:我有一个在Xcode中运行的程序,它有一堆print()语句,可以很好地将输出打印到调试控制台。然而,我希望也能够将这些输出重定向到一个文件,这样我就可以让用户将它们发送给我,作为调试的一种方式。 SO上找到的解决方案使我可以将输出重定向到文件,但调试控制台输出将丢失。 问:我想要我的蛋糕和吃它。我希望能够将print()语句重定向到调试控制台和文件。 所以我有引用:https://st

  • 在航站楼如何做到这一点?