存储库中的Spring数据JPA继承

存储库中的Spring数据JPA继承,spring,spring-data-jpa,Spring,Spring Data Jpa,我有一个用@MappedSuperClass注释的抽象类。大约有15个实体扩展了这个抽象类,在数据库中有15个对应的表。这15个实体都具有从抽象超类继承的相同属性 我为抽象类创建了一个存储库,如下所示: @NoRepositoryBean public interface AbstractRepository <T extends AbstractClass, E extends Serializable> ex

我有一个用@MappedSuperClass注释的抽象类。大约有15个实体扩展了这个抽象类,在数据库中有15个对应的表。这15个实体都具有从抽象超类继承的相同属性

我为抽象类创建了一个存储库,如下所示:

@NoRepositoryBean
public interface AbstractRepository <T extends AbstractClass, E extends Serializable>
                                    extends PagingAndSortingRepository<T, Serializable> {
  .....some methods here
}

15个实体/表格存储与15个独立设备相关的一些数据。根据所选设备,将检索该表中的数据。我是否必须为15个具体实体创建15个单独的存储库,或者是否有任何方法仅使用抽象存储库获取所选设备的特定实体?如果需要为每个具体实体创建存储库,如何为特定设备调用获取正确的存储库?将表名和repository类存储在应用程序启动时创建的映射中可能?

您必须为每个类创建存储库。但是,您可以将方法保持在抽象状态。您需要在每个方法上提供@Query,并使用SpeLSpring表达式语言将类型添加到查询中

@NoRepositoryBean
public interface AbstractRepository<T extends AbstractEquipment> 
        extends CrudRepository<T, Long>{

 @Query("select e from #{#entityName} as e from equipment where e.name = equipmentName")
 T findEquipmentByName(String equipmentName);

}
然后像下面这样扩展

@Transactional
public interface SpecialEquipmentRepo extends AbstractRepository<SpecialEquipment,Long>{

}

理想情况下,以下设置应起作用:

实体类

存储库接口

也就是说,这个设置可能无法与Hibernate一起使用,我怀疑您正在使用Hibernate。Hibernate不支持具有表每类继承的自动递增标识符列。因此,尝试使用Hibernate运行上面的设置将引发异常。这可以通过在上面链接的示例上运行以下命令来验证

mvn test -Dspring.profiles.active="default,hibernate"

感谢@Joseph的澄清。由于需要创建每个设备的存储库,那么获取特定设备的存储库实例的更好方法是什么?一种方法是自动连接所有15个存储库,并有一个开关盒,根据传递的设备使用正确的存储库实例,例如工厂返回正确的存储库。我将避免使用开关,因为这需要维护,您可以@autowire一个键为类型的映射,这个值是存储库类型,@NoRepositoryBean是使用存储库继承的关键提示,谢谢!
public interface EquipmentRepository<T extends Equipment> extends CrudRepository<T> {}
@Service
public class SomeService {
  @Autowired
  private EquipmentRepository<Crane> craneRepository;

  @Autowired
  private EquipmentRepository<Excavator> excavatorRepository;
}
mvn test -Dspring.profiles.active="default,eclipselink"

mvn test -Dspring.profiles.active="default,openjpa"
mvn test -Dspring.profiles.active="default,hibernate"