存储库中的 Spring Data JPA 继承

问题描述 投票:0回答:3

我有一个用

@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 个单独的存储库,或者有什么方法可以仅使用抽象存储库来获取所选设备的特定实体?如果需要为每个具体实体创建存储库,如何为特定设备调用获取正确的存储库? (将表名称和存储库类存储在应用程序启动时创建的映射中?)

spring spring-data-jpa
3个回答
20
投票

理想情况下,以下设置应该有效:

实体类

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Equipment { ... }

@Entity
public class Crane extends Equipment {}

@Entity
public class Excavator extends Equipment {}

存储库界面

public interface EquipmentRepository<T extends Equipment> extends CrudRepository<T> {}

存储库消费者

@Service
public class SomeService {
  @Autowired
  private EquipmentRepository<Crane> craneRepository;

  @Autowired
  private EquipmentRepository<Excavator> excavatorRepository;
}

我已经在 Github 上建立了一个示例项目来演示这一点。按照以下任一方式运行 Maven 测试将显示通过测试,以证明设置按预期工作。

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


也就是说,此设置可能不适用于 Hibernate,我怀疑您正在使用 Hibernate。 Hibernate 不支持具有

TABLE_PER_CLASS

 继承的自动递增标识符列。因此,尝试使用 Hibernate 运行上述设置将引发异常。这可以通过在上面链接的示例上运行以下命令来验证。

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

16
投票
您必须为每个课程创建存储库。然而,您可以将您的方法保持在抽象中。您需要在每个方法上提供

@Query

 并使用 SpeL(Spring 表达式语言)将类型添加到查询中。

@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>{ }
    

0
投票
@Transactional public interface SpecialEquipmentRepo extends AbstractRepository<SpecialEquipment,Long>{ }
此代码给出以下错误:类型参数的数量错误:2;需要:1

我猜你的解决方案有问题。

我仍然对父存储库的使用感到困惑,我应该将其用于公共方法,还是应该只使用子存储库并为每个实体重复方法!!

© www.soinside.com 2019 - 2024. All rights reserved.