Jpa Spring MVC、InheritanceType.JOINED和JSON对象到具有Jackson的实体的自动映射
我们正在尝试编写一个API来创建不同类型的元素。元素具有JPA实体表示。下面的代码显示了基本元素结构的外观(简化): 每个元素实现看起来都不一样,但这个示例应该足够了:Jpa Spring MVC、InheritanceType.JOINED和JSON对象到具有Jackson的实体的自动映射,jpa,spring-mvc,jackson,Jpa,Spring Mvc,Jackson,我们正在尝试编写一个API来创建不同类型的元素。元素具有JPA实体表示。下面的代码显示了基本元素结构的外观(简化): 每个元素实现看起来都不一样,但这个示例应该足够了: import javax.persistence.Column; import javax.persistence.Entity; @Entity public class SpecializedElement1 extends Element { @Column private String attribu
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
public class SpecializedElement1 extends Element {
@Column
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
我们使用Jackson,典型的控制器动作如下所示:
@RequestMapping(value = "/createElement", method = RequestMethod.POST)
@ResponseBody
public HashMap<String, Object> create(@RequestBody Element element) {
HashMap<String, Object> response = new HashMap<String, Object>()
response.put("element", element);
response.put("status", "success");
return response;
}
{
"type": "constantStringForSpecializedElement1"
"text": "Bacon ipsum dolor sit amet cow bacon drumstick shankle ham hock hamburger."
}
正如您将看到的:这不起作用,因为Jackson不知道如何将此对象映射到SpecializedElement1
问题是:我怎样才能让它工作呢?我想出来了。这就是解决方案:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@JsonTypeInfo(
// We use the name defined in @JsonSubTypes.Type to map a type to its implementation.
use = JsonTypeInfo.Id.NAME,
// The information that stores the mapping information is a property.
include = JsonTypeInfo.As.PROPERTY,
// The property is called "type".
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = SpecializedElement1.class, name = "specializedElement1"),
@JsonSubTypes.Type(value = SpecializedElement1.class, name = "specializedElement2")
})
public class Element {
// ....
}
此控制器操作按预期工作
@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> create(@RequestBody Element element) {
if (element == null) {
// Return an error response.
}
try {
return elementService.update(element);
} catch (Exception e) {
// Return an error response.
}
}
@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> create(@RequestBody Element element) {
if (element == null) {
// Return an error response.
}
try {
return elementService.update(element);
} catch (Exception e) {
// Return an error response.
}
}
POST /create/
... more headers ...
Content-Type: application/json
{
"type": "specializedElement1"
}