[英]Spring findAll() method in CrudRepository doesn't return derived entities
So I have the following application, which has one entity called Product
that inherits two other entities (Product > Bike, Product > Wheel).所以我有以下应用程序,它有一个名为
Product
的实体,它继承了另外两个实体(产品 > 自行车,产品 > 车轮)。 Controllers look like this:控制器如下所示:
public abstract class ProductController<T extends Product> {
@Autowired
private ProductService<T> productService;
@PostMapping
public ResponseEntity post(@RequestBody T product) {
return ResponseEntity.ok(productService.save(product));
}
@GetMapping
public ResponseEntity get() {
return ResponseEntity.ok(productService.findAll());
}
}
@RestController
@RequestMapping("/products/categories/bikes")
public class BikeController extends ProductController<Bike> {}
@RestController
@RequestMapping("/products/categories/wheels")
public class WheelController extends ProductController<Wheel> {}
Entities:实体:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Product() {}
//getters and setters
}
@Entity
public class Bike extends Product {
private String color;
public Bike() {}
//getters and setters
}
@Entity
public class Wheel extends Product {
private Double diameter;
public Wheel() {}
//getters and setters
}
Product repository:产品仓库:
public interface ProductRepository<T extends Product> extends CrudRepository<T, Long> {}
Product service:产品服务:
@Service
public class ProductService<T extends Product> {
@Autowired
private ProductRepository<T> productRepository;
public T save(T product) {
return productRepository.save(product);
}
public Iterable<T> findAll() { return productRepository.findAll(); }
}
After running the program it creates three tables for each entity.运行程序后,它为每个实体创建三个表。 If i call the
post
method from the concrete controller it adds the entity to its table.如果我从具体控制器调用
post
方法,它会将实体添加到其表中。 But the findAll() method returns entities not from the concrete table but from the product table.但是 findAll() 方法不是从具体表而是从产品表返回实体。 So my question is why is this happening (even if i specified the Entity type in the repository)?
所以我的问题是为什么会发生这种情况(即使我在存储库中指定了实体类型)?
What you want to achive is impossible because Bike
is a subtype of Product
in java but not for JPA.您想要实现的目标是不可能的,因为
Bike
是 Java 中Product
的子类型,但不适用于 JPA。 In the Database it usally split into different Tables for each Subtype and only the tables (seen by JPA as entites) can be queried.在数据库中,它通常为每个子类型拆分为不同的表,并且只能查询表(JPA 将其视为实体)。 So a Spring Repository can't query it either, because it uses JPA internally.
所以 Spring Repository 也不能查询它,因为它在内部使用 JPA。
Please take a look here and read more about jpa inheritance: https://www.baeldung.com/hibernate-inheritance请在此处查看并阅读有关 jpa 继承的更多信息: https ://www.baeldung.com/hibernate-inheritance
Generally: It is bad pratice to have different table for each Type of Product.一般来说:为每种产品类型设置不同的表格是不好的做法。 Everytime you add a new Product you would have to add a whole new class and table in database.
每次添加新产品时,都必须在数据库中添加一个全新的类和表。 It is best practice to just have a single entity/class (and thus a single table) for
Product
and a field to distinguish between different types of products.最佳实践是只为
Product
提供一个实体/类(因此是一个表)和一个字段来区分不同类型的产品。 In it's simplest form a String productType
, but i would recommand using a seperate Entity ProductType
with an id and name (in its simplest form) and have a @OneToMany
relation between Product
and ProductType
.最简单的形式是
String productType
,但我建议使用带有 id 和 name 的单独实体ProductType
(以最简单的形式),并且Product
和ProductType
之间有@OneToMany
关系。 Additonal data like color
and diameter
could be stored using a field of type Map
with @ElementCollection
or in a another entity for (dynamic) additional data (as seen here: https://stackoverflow.com/a/15061468/7142748 ). color
和diameter
等附加数据可以使用带有@ElementCollection
的Map
类型字段存储,也可以存储在另一个实体中以存储(动态)附加数据(如下所示: https ://stackoverflow.com/a/15061468/7142748)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.