如何解决Spring REST API - 发布一对一实体 - 无法弄清楚如何使用一对一关系发布 JSON 实体并对其进行测试
我很难决定如何处理两个实体之间的 @OneToOne 关系。我在后端有 SpringBoot,在前端有 Angular 10。我想制作一个 restfull API 并添加测试以避免使用 Postman 自己测试它,但我无法做到。
当我将解析为 JSON 的完整实体发送到我的控制器 (POST) 时,我得到了
org.hibernate.PropertyValueException: not-null property references a null or transient value : com.macawena.autonhome.entities.Land.advert
这些是我的实体广告和土地。
广告:
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "advert")
public class Advert implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(unique = true)
private long id;
@OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL,mappedBy = "advert")
private Land land;
@NotNull
private String title = "New Advert";
private String description;
private int price;
public Advert() {
this.price = 0;
}
public Advert(String title) {
this();
this.setTitle(title);
}
// Getters and setters..
}
土地:
@Entity
@Table(name = "land")
public class Land {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@OneToOne(fetch = FetchType.LAZY,optional = false)
@JoinColumn(name = "advert_id",nullable = false)
private Advert advert;
@Column(name = "surface")
private int surface;
public Land() {
}
public Land(int surface) {
super();
setSurface(surface);
}
// Getters and setters
}
如果 Land 字段为空,我可以毫无问题地发布我的广告。
我的 RestController:
@RestController()
@RequestMapping(path = "/",produces = MediaType.APPLICATION_JSON_VALUE)
public class AdvertController {
@Autowired
private AdvertRepository advertRepository;
@PostMapping(value = "/adverts",consumes = "application/json",produces = "application/json")
public ResponseEntity<Advert> createAdvert(@RequestBody Advert advert) {
Advert saved = advertRepository.save(advert);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.port(8080)
.path("/{id}")
.buildAndExpand(saved.getId())
.toUri();
return ResponseEntity.created(location).build();
}
}
以及通过的@Test:
@Test
void POSTReturnCode201WithCorrectURI() throws Exception {
String uri = "/adverts";
Advert advert = new Advert();
mvc.perform(MockMvcRequestBuilders
.post(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(super.mapToJson(advert)))
.andExpect(status().isCreated())
.andExpect(header().string(HttpHeaders.LOCATION,"http://localhost:8080/adverts/1")).andReturn();
}
现在我想用土地进行测试、发布和广告。我应该如何进行?
这是我编写的用于测试 PostAdvertWithLand 的测试:
@Test
void POSTAdvertWithLand() throws Exception {
String uri = "/adverts";
Advert advert = new Advert();
Land land = new Land();
land.setSurface(500);
land.setAdvert(advert);
advert.setLand(land);
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders
.post(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(super.mapToJson(advert)))
.andExpect(status().isCreated())
.andExpect(header().string(HttpHeaders.LOCATION,"http://localhost:8080/adverts/1"))
.andReturn();
}
super.mapToJson(advert) 输出
{"id":2,"land":{"id":1,"surface":5000},"title":"New Advert","description":null,"price":0}
对应的测试错误:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : com.macawena.autonhome.entities.Land.advert; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.macawena.autonhome.entities.Land.advert
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。