我正在写一个Spring应用程序,其中有两个是由一个一对多的关系相关的实体,可以打电话给他们的母亲和孩子。
通过POST请求创建母实体时,我希望自动创建一个孩子实体。使用@OneToMany和@ManyToOne批注,效果很好。至少,只要我提供MotherService内孩子的信息。
这是我的代码
Mother.java
@Entity
@Table(name="mother")
public class Mother{
@Id
@Column(name="id", updatable = false, nullable = false)
private Long id;
@Column(name="name")
private String name;
@OneToMany(mappedBy = "mother", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Kid> kidList = new ArrayList<>();
//constructor, getter, setter
private void addKid(Kid kid) {
this.kidList.add(kid);
kid.setMother(this);
}
}
Kid.java
@Entity
@Table(name="kid")
public class Kid{
@Id
@Column(name="id", updatable = false, nullable = false)
private Long id;
@Column(name="name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "mother_id", nullable=false)
private Mother mother;
//constructor, getter, setter
}
MotherController.java
@RestController
@RequestMapping("mothers")
public class MotherController {
@Autowired
private MotherService motherService;
MotherController(MotherService motherService) {
this.motherService = motherService;
}
@PostMapping
Mother createMother(@RequestBody Mother mother) {
return this.motherService.createMother(mother);
}
}
MotherService.java
@Service
public class MotherService {
private MotherRepository motherRepository;
@Autowired
public MotherService (MotherRepository motherRepository) {
super();
this.motherRepository= motherRepository;
}
public Mother createMother(Mother mother) {
Kid kid = new Kid("Peter");
mother.addKid(kid);
return this.motherRepository.save(mother);
}
}
对母亲和孩子的储存库,没有任何定制方法延长JpaRepository为止。
我的POST请求类似于(使用邮递员)
{
"name":"motherName"
}
现在创建了一个名为“ motherName”的母亲和一个名为“ Peter”的孩子。
我的想法:使用DTO
我现在尝试实现一个DTO,其中包含母亲的名字和孩子的名字,将此信息在MotherService中映射到实体,并通过相应的存储库保存它们,因此我可以在POST请求中定义这两个名字。 / p>
motherDto.java
public class mother {
private String motherName;
private String kidName;
//getter, setter
}
所以当我发布
{
"motherName":"Susanne",
"kidName":"Peter"
}
甚至更好
{
"mother": {
"name":"Susanne"
},
"kid": {
"name":"Peter"
}
}
创建了一个名字叫Susanne的母亲和一个名字叫Peter的孩子。
我的问题是
如何将DTO映射到两个实体?
还是我做错了什么?有没有更简单的方法可以实现我的目标?
答案 0 :(得分:1)
第一个解决方案:
您不能使用DTO并以JSON
和Mother
中的kids
和Jackson
和Spring MVC
相同的结构来发送{
id:2,
name:'sarah'
kidList:[{id:546,name:'bob'},{id:478,name:'tom'}]
}
JSON
第二个解决方案:
如果您想在@JsonProperty
和模型中使用不同的结构,则可以使用@JsonDeserialize
或DozzerMapper
之类的Jackson注释。阅读this like了解更多信息。
第三种解决方案:
您可以使用DTO
在DTO
和模型之间进行复杂的映射。您可以定义XML文件,以将每个模型映射到您的DozzerMapper
和DTO
将您的class Statement {
public:
Statement();
~Statement();
void BindInt(int index, int value);
void BindInt(std::string name, int value);
void BindInt64(int index, int value);
void BindInt64(std::string name, int value);
void BindText(int index, std::string value);
void BindText(std::string name, std::string value);
};
Statement::Statement(){}
Statement::~Statement(){}
void Statement::BindInt(int index, int value){}
void Statement::BindInt(std::string name, int value){}
void Statement::BindInt64(int index, int value){}
void Statement::BindInt64(std::string name, int value){}
void Statement::BindText(int index, std::string value){}
void Statement::BindText(std::string name, std::string value){}
映射到您的模型。有关详细信息,请阅读this link。
答案 1 :(得分:1)
您有2种方法:
答案 2 :(得分:1)
我知道这很久了,也许已经解决了,但是让我对这个问题提出不同的看法。
另一个选择是仅设计DTO来创建您提到的两个实体。您可以将其称为MotherChildCreationDTO或类似名称,以便该名称已经传达了其用法,并可能创建一个使用DTO的REST目标。
非对称DTO(接收和发送)是一种已建立的模式,并且DTO以任何方式与REST控制器紧密耦合。