Rest 如何在@manytone单向映射中使用spring boot保存包含子对象的父对象?
我是新来的春天靴子。我有两个模型类Party(家长)和PartyCategory(孩子)。PartyCategory成功存储数据id、labelAr和labelEn 现在我在json请求中传递子id,并在json响应中获取labelAr和labelEn的空值,如下所示。有人能帮我做点什么吗 我也粘贴了我的代码 Json请求:Rest 如何在@manytone单向映射中使用spring boot保存包含子对象的父对象?,rest,spring-boot,spring-mvc,spring-data-jpa,jackson,Rest,Spring Boot,Spring Mvc,Spring Data Jpa,Jackson,我是新来的春天靴子。我有两个模型类Party(家长)和PartyCategory(孩子)。PartyCategory成功存储数据id、labelAr和labelEn 现在我在json请求中传递子id,并在json响应中获取labelAr和labelEn的空值,如下所示。有人能帮我做点什么吗 我也粘贴了我的代码 Json请求: { "name": "Party A", "description": "Description of Party A", "category":
{
"name": "Party A",
"description": "Description of Party A",
"category": {
"id": 1
}
}
Json响应
{
"id": 6,
"name": "Party A",
"description": "Description of Party A",
"category": {
"id": 1,
"labelAr": null,
"labelEn": null
}
}
Party.java:
public class Party {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private String description;
@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinColumn(name = "category_id")
private PartyCategory category;
....setters and getters
}
PartyCategory.java:-
public class PartyCategory {
@Id
@GeneratedValue
private Integer id;
private String labelAr;
private String labelEn;
...setters and getters..
存储库:
public interface PartyCategoryRepository extends JpaRepository<PartyCategory, Integer> {
}
public interface PartyRepository extends JpaRepository<Party, Integer> {
}
控制器:
@RestController
public class PartyController {
@Autowired
PartyServiceImpl partyServiceIml;
@PostMapping(value = "/party/save")
public Party saveParty(@RequestBody Party party ) {
Party returnedParty = partyServiceIml.saveParty(party);
return returnedParty;
}
}
首先,对数据库和rest服务使用相同的实体不是一个好的做法。它们应该是独立的实体,通常rest服务的实体称为DTO(数据访问对象) 现在,关于您的问题,代码中发生的事情是正常的,因为在保存新参与方时,您使用空值覆盖与ID 1关联的PartyCategory labelAr和labelEn,因为您没有为这两个标签提供任何值
return partyRepository.save(party);
如果要避免此问题,必须首先从数据库检索PartyCategory数据,设置为Party实体,然后将其保存到数据库。大概是这样的:
public class PartyServiceImpl {
@Autowired
PartyRepository partyRepository;
@Autowired
PartyCategoryRepository partyCategoryRepository;
public Party saveParty(Party party) {
PartyCategory partyCategory = partyCategoryRepository.findById(party.getPartyCategory().getId());
party.setPartyCategory(partyCategory);
return partyRepository.save(party);
}
问题是您发布的类别未被识别为现有类别 然后,您可以执行以下操作。首先,创建一个Jackson converter类来定制Json反序列化。我不确定这些是否是Spring管理的,但它们是这样的,这样您就可以注入必要的存储库
import com.fasterxml.jackson.databind.util.StdConverter;
@Component
public class CategoryConverter extends StdConverter<Integer, PartyCategory> {
@Autowired
private PartyCategoryRepository repo;
@Override
public PartyCategory convert(Integer value) {
return repo.findById(value).get();
}
}
然后您可以发布JSON,如下所示,我们只需指定现有类别的id即可:
{
"name": "Party A",
"description": "Description of Party A",
"category": 1
}
通过按照建议增强此解决方案以使用mix-ins,可以将视图模型与实体模型清晰地分离,而无需创建DTO层,DTO层通常会在很大程度上复制实体模型,并且需要繁琐的映射代码来处理转换
@Entity
public class Party {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private String description;
@ManyToOne
@JoinColumn(name = "category_id")
@JsonDeserialize(converter = CategoryConverter.class) //in real life use a 'mix-in'
private PartyCategory category;
}
{
"name": "Party A",
"description": "Description of Party A",
"category": 1
}