java - 具有单表继承的 JPA 存储库( hibernate )

标签 java spring hibernate jpa

我创建了两个实体( RegularEmployeeContactEntity )来扩展 Employee实体。

@Entity
@Table(name="employees")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value="employee")
public class Employee {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

...
我正在使用 SINGLE_TABLE继承这个实现,并创建了一个通用的 JpaRepository 来操作数据:
@Repository
public interface EmployeeRepository<T extends Employee> extends JpaRepository<T, Long> {
}
我还创建了 Service 类,它 Autowiring 这些通用存储库的三个实例,以及每个类的特定方法。
@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository<Employee> employeeRepo;

    @Autowired
    private EmployeeRepository<RegularEmployee> regularRepo;

    @Autowired
    private EmployeeRepository<ContractEmployee> contractRepo;

    public List<Employee> getAllEmployee() {
        return employeeRepo.findAll();
    }

    public List<RegularEmployee> getAllRegularEmployee(){
        return regularRepo.findAll();
    }

    public List<ContractEmployee> getAllContractEmployee() {
        return contractRepo.findAll();
    }
...

我的问题是,当我试图找到所有正式员工或契约(Contract)员工时,我总是得到所有类型的员工(员工、正式员工和契约(Contract)员工)。
我不知道为什么它会这样,即使方法的签名说它返回适当的类型。

最佳答案

一种选择是使用 @QueryEmployeeRepository :

public interface EmployeeRepository<T extends Employee> extends JpaRepository<T, Long> {
    @Query("from RegularEmployee")
    List<RegularEmployee> findAllRegularEmployees();
}
第二种选择是为 Employee 的每个子类创建一个额外的存储库。 .对于 RegularEmployee将是:
public interface RegularEmployeeRepository extends EmployeeRepository<RegularEmployee>{}
这是在 EmployeeService 中使用这两个选项的方法:
@Service
public class EmployeeService {
    @Autowired EmployeeRepository<Employee> employeeRepo;

    @Autowired EmployeeRepository<RegularEmployee> regularRepoT;

    @Autowired RegularEmployeeRepository regularRepo;

    @PostConstruct
    public void init(){
        employeeRepo.save(new ContractEmployee("Mark"));
        employeeRepo.save(new RegularEmployee("Luke"));
        employeeRepo.findAll().forEach(System.out::println); // prints Mark and Luke
        regularRepo.findAll().forEach(System.out::println); // prints only Luke
        regularRepoT.findAllRegularEmployees().forEach(System.out::println); // prints only Luke
    }
//...
}
您也可以省略 @Repository顶部 EmployeeRepository . Spring 已经知道这是一个存储库,因为它扩展了 JpaRepository .
旁注 : 如果你不需要 EmployeeRepository由 Spring 创建添加 @NoRepositoryBean在同类产品之上。

关于java - 具有单表继承的 JPA 存储库( hibernate ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63656497/

相关文章:

java - 旋转后模型的顶点选择和状态

spring - 获取请求 header 名称和值

spring - 把阻塞代码包装成一个Mono flatMap,这还是非阻塞操作吗?

java - 如何解决 IllegalArgumentException : Target object must not be null

java - 使用QueryDSL消除hibernate hql parser

没有硬件设备的java声音

java - 如何仅在 Spring Security 上对某些 URL 强制使用 https?

java - 如何将 Excel 工作表中的第一行(标题)存储在一个 HashMap 中,并将列数据存储在另一个 HashMap 中

java - Spring异步线程 hibernate

java - ID 字段为 "Repeated column in mapping for entity"