【发布时间】:2018-10-23 07:23:55
【问题描述】:
我做了一些研究,我已经通过this guide。
这是我的实体结构:
@MappedSuperClass
public abstract class Item{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false)
private String name;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "item_id")
private Set<Picture> pictures = new HashSet<>();
}
示例项目 1:
@Entity
public class Coke extends Item{
@Column
private String cokeProperty;
@Column
private String cokeProperty2;
}
示例项目 2:
@Entity
public class Sprite extends Item{
@Column
private String spriteProperty;
@Column
private String spriteProperty2;
}
抽象类Item使用的图片类:
@Entity
public class Picture {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
}
所有这些都有构造函数、getter 和 setter 以及 toString 覆盖。我这样做是因为我想要Items 的表,然后为Coke 和Sprite 分开表,每个表都包含来自Items_table 的外键id。此外,我假设它还会为Pictures 创建一个表,该表还具有来自Items_table 的外键。然而,我想不通的是如何为此实现 Spring Boot 和 JPA。我以为就这么简单
在 application.properties 中配置了 h2 数据库的项目的我的存储库
@Repository
public interface ItemRepository<Item, Long>{
}
实现ItemService 接口并接受ItemRepository bean 的我的服务:
@Service
public class ItemServiceImpl implements ItemService{
private ItemRepository repository;
public ItemServiceImpl(ItemRepository repository) {
this.repository = repository;
}
@Override
public ResponseEntity<List<Item>> getAll(){
return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
}
@Override
public ResponseEntity<Item> getById(Long id){
Optional<Item> item = repository.findById(id);
return new ResponseEntity<>(item.orElse(null), HttpStatus.OK);
}
@Override
public ResponseEntity<Item> create(Item item){
return new ResponseEntity<>(repository.save(item), HttpStatus.CREATED);
} }
然后是我的控制器,它接收一个ItemService bean:
@RestController
@RequestMapping("/api/items")
public class ItemController{
private ItemService service;
public ItemController(ItemService service) {
this.service = service;
}
@GetMapping("")
public ResponseEntity<List<Item>> findAll(){
return service.getAll();
}
@GetMapping("/{id}")
public ResponseEntity<Item> findById(@PathVariable(name = "id") Long id){
return service.getById(id);
}
@PostMapping("")
public ResponseEntity<Item> save(@RequestBody Item item){
return service.create(item);
}
}
但是当我POST 使用 Json Data 之类的
{
"name": "Toyota Civic 3 days sale!!",
"pictures": [
{
"name": "picture 1"
},
{
"name": "picture 2"
}
],
"cokeProperty": "sweet",
"cokeProperty2": "not healthy"
}
我收到此错误:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 不能 构造
com.example.demo.entities.product.Item的实例(没有 创建者,如默认构造,存在):抽象类型要么需要 映射到具体类型,具有自定义反序列化器,或包含 [Source: (PushbackInputStream); 处的附加类型信息;线: 1、栏目:1]
我还在我的抽象类上尝试了另一种策略:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
仍然没有雪茄。同样的错误。有人可以告诉我将 Spring Boot 和 JPA 用于由其他实体扩展的抽象实体的正确方法吗?
【问题讨论】:
-
errm,那个错误是 JSON,而不是 JPA。 JSON 是一个单独的过程。也许您应该将您的问题标记为
json和jackson而不是 JPA -
首先,您似乎刚刚开始使用 java 并为此竖起大拇指。其次.. 错误消息是说 you cannot directly insert data into **Item class.. 因为,它被注释为 @MappedSuperClass 和抽象,你可以通过扩展来插入数据你用 coke 和 sprite 做的。像使用 Item 一样制作 coke 和 sprite 的存储库...第三,您在 private ItemRepository 存储库中缺少 @Autowired 注释ItemServiceImpl的和私有ItemService服务;的ItemController。
-
@RujalShrestha 我只是简单地为可乐和雪碧创建一个存储库吗?我可以问一下是什么让我看起来好像刚开始使用 Java 吗?我想知道我可以改进的地方。而且,我认为从版本 4 开始,Spring Boot 中不再需要
@Autowired注释。
标签: java json spring spring-boot spring-data-jpa