我创建了两个实体( RegularEmployee
和 ContactEntity
)来扩展 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)员工)。我不知道为什么它会这样,即使方法的签名说它返回适当的类型。
最佳答案
一种选择是使用 @Query
在 EmployeeRepository
:
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/