简体   繁体   English

CrudRepository 中的 Spring findAll() 方法不返回派生实体

[英]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 (以最简单的形式),并且ProductProductType之间有@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 ). colordiameter等附加数据可以使用带有@ElementCollectionMap类型字段存储,也可以存储在另一个实体中以存储(动态)附加数据(如下所示: https ://stackoverflow.com/a/15061468/7142748)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM