![](/img/trans.png)
[英]How to correctly map a OneToMany relationship in Spring Boot?
[英]How to implement API returns nested JSON with OneToMany relationship in Spring Boot?
我正在为练习项目在线购物系统开发简单的API。 我对Spring Boot框架和创建API完全陌生。
我想返回类似于以下内容的JSON:
[
{
"id": 1,
"name": "pname_46",
"description": "pdesc_793_793_793_79",
"price": 519.95,
"details": [{"orderId": 10,
"productId": 1,
"quantity": 4
}
{"orderId": 12,
"productId": 1,
"quantity": 5
}]
},
{
"id": 2,
"name": "pname_608",
"description": "pdesc_874_874_874",
"price": 221.7,
"details": [{"orderId": 20,
"productId": 2,
"quantity": 2
}
{"orderId": 3,
"productId": 2,
"quantity": 67
}]
}]
这是我的@Entity
类:
Product.java
@Entity
@Table(name = "Products")
public class Product implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "pcod")
private int id;
@Column(name = "pnam")
private String name;
@Column(name = "pdes")
private String description;
@Column(name = "price")
private Double price;
@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Detail> details = new ArrayList<>();
//Constructor, setter, and getter ..
}
Detail.java
@Entity
@Table(name = "Details")
public class Detail {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ordid")
private Order order;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pcod")
private Product product;
@Column(name = "qty")
private int quantity;
//constructor, setters, and getters ..
}
还有一个类似于Product.java的名为Order.java的类。
ProductRepository.java
@Repository
public interface ProductRepository extends JpaRepository<Product, Integer> {
}
OnlineShoppingApiController.java
@RestController
public class OnlineShoppingApiController {
@Autowired
ProductRepository productRepository;
@GetMapping("/products")
public List<Product> getAllProducts(){
return productRepository.findAll();
}
@GetMapping("/products/id={id}")
public Optional<Product> getOneProduct(@PathVariable String id){
int pid = Integer.parseInt(id);
return productRepository.findById(pid);
}
}
ProjectApplication.java
@SpringBootApplication
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
该程序从MySql数据库获取数据。 表中存储了数据。
表格如下所示:
产品介绍:
-pcod
-pnam
-pdes
- 价钱
细节:
-Ordid
-pcod
-数量
这是我的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>project</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
当我运行应用程序并使用POSTMAN检查API时,得到以下结果:
{
"timestamp": "2018-04-04T13:39:44.021+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Could not write JSON: could not extract ResultSet; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->com.example.project.pojo.Product[\"details\"])",
"path": "/products"
}
我怎么解决这个问题?
感谢您的回答
当将您的Product
实体转换为Json时,该产品具有一个Details
List,这些详细信息也将转换为Json,但是它们再次引用该Product
,并且此过程开始且无休止,从而导致错误。
一个解决方案可能是在关系的一侧添加@JsonIgnore
@Entity
public class Detail {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pcod")
@JsonIgnore
private Product product;
...
}
在两个实体中使用@JsonManagedReference和@JsonBackReference批注也可以解决该问题。 请参阅有关Jackson双向关系的本文 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.