如何在spring boot中开发JPA双向实体

Posted

技术标签:

【中文标题】如何在spring boot中开发JPA双向实体【英文标题】:how to develop JPA bi-directional entities in spring toot 【发布时间】:2016-08-19 16:10:31 【问题描述】:

我是 Spring Boot 和 jpa/hibernate 的新手,请承担我对术语的不准确使用。

我有两个实体:书和地址。一本书在某个城市出版,存储在“地址”中,一个“地址”可以出版多本书。 book 的数据库模式是:id、name、author、price、addressid 地址架构:addressid、addressCountry、addressCity 书的实体:

@Entity
@Table(name = "test_book")
public class Book implements Serializable 
private static final long serialVersionUID = 8025948150436422040L;
@Id
long id;

@Column(name = "name")
String name;

@Column(name = "author")
String author;

@Column(name = "price")
long price;

@ManyToOne
@JoinColumn(name = "addressid")
private Address address;
...//getter and setter

地址的实体

@Entity
@Table(name = "test_address")
public class Address implements Serializable
private static final long serialVersionUID = -3541059157210384355L;
@Id
@Column(name= "addressid")
private long addressId;

@Column(name="addresscountry")
private String addressCountry;

@Column(name="addresscity")
private String addressCity;

@OneToMany(mappedBy = "address")
private Collection<Book> books;
...//getter setter

但是当我调用 Restful 服务时,我得到了无限循环......

["id":11,"name":"Java Book","author":"Jame Gosling","price":100,"address":"addressId":1,"addressCountry": "China","addressCity":"Shanghai","books":["id":11,"name":"Java Book","author":"Jame Gosling","price":100,"address “:……

我做了一些搜索。我的要求是: 当我搜索一本书时,我可以获得以下信息:id、姓名、作者、价格、地址.. 我还可以查询地址以获取该市出版的所有书籍。 当我在地址中添加Json Annotation @JsonManagedReference 和在书籍实体中添加@JsonBackReference 时,我可以查询书籍但无法获取地址信息。

您能帮忙解决一下问题吗?非常感谢。

【问题讨论】:

如果您不需要将书籍退回到某个地址或其他方式,请查看JsonView 的概念。否则,您可以调整对象注释以返回引用实体的 ID 或 URI,例如使用 HATEOAS。 对不起,我没有说清楚。我想退书有地址,查询地址时,列出地址和从那里出版的所有书籍。 【参考方案1】:

您可以忽略书籍吸气剂上的@JsonIgnore。这将从序列化地址中排除Collection&lt;Book&gt; books 属性。

链接:JacksonAnnotations - Faster XML Wiki

例子:

@JsonIgnore
public Collection<Book> getBooks() 
...

【讨论】:

【参考方案2】:

@JsonIgnore

Jackson 注解@JsonIgnore 用于告诉Jackson 忽略一个 Java 对象的某些属性(字段)。该属性被忽略 将 JSON 读入 Java 对象和编写 Java 时 对象转换成 JSON。

在您的情况下,这种情况正在发生,因为存在双向关系,因此它将进入循环。要阻止这种情况,您需要提供 JsonIgnore

所以你的代码会是这样的:

-> 地址的实体

@Entity
@Table(name = "test_address")
public class Address implements Serializable
private static final long serialVersionUID = -3541059157210384355L;
@Id
@Column(name= "addressid")
private long addressId;

@Column(name="addresscountry")
private String addressCountry;

@Column(name="addresscity")
private String addressCity;

@OneToMany(mappedBy = "address")
@JsonIgnore
private Collection<Book> books;

【讨论】:

谢谢 Riddhi Gohil。使用@JsonIgnore,我可以搜索地址并获取地址信息以及从该地址出版的书籍吗?

以上是关于如何在spring boot中开发JPA双向实体的主要内容,如果未能解决你的问题,请参考以下文章

外键在一对多关系中始终为空 - Spring Boot Data with JPA

如何在Jpa中使用所选实体创建行,RestController Spring Boot

如何在 Spring Boot 中实现通用 JPA 存储库 - 它可以自动装配到任何实体/类类型的 Spring 服务中

Spring boot之 JPA/Hibernate/Spring Data

Spring Boot:如何从 JPA/Hibernate 注释中保持 DDD 实体的清洁?

如何只扫描一个具体的 JPA 实体,但不是所有实体都使用 spring-boot 放在同一个包中?