假设我有一个抽象实体
@MappedSuperclass
@Data
public abstract class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false, updatable = false)
protected Integer id;
@Column(nullable = false, unique = true)
protected String name;
}
使用某种 AbstractRepository
@NoRepositoryBean
public interface AbstractRepository<C extends AbstractEntity> extends JpaRepository<C, Integer> {}
这应该充当多个实体的单个依赖项。实体扩展了抽象实体,从而扩展了 AbstractRepository:
public interface RealEntityRepository extends AbstractRepository<RealEntity> {}
在我的服务中,我想使用 jpa 继承来摆脱臃肿的构造函数(由于 realEntityRepos 太多而变得臃肿)和每个实体的方法实现。因此,而不是每个实体都有 x 个这样的方法
void findRealEntity(RealEntity entity) {
entity.setId(realEntityRepository.findOne(entity.getName())
.map(RealEntity ::getId)
.orElseThrow(() -> new SomeException(entity.getName())));
}
我只想有一个方法调用,如下面的伪代码(我知道无法实例化抽象类),该方法将实体作为参数的抽象实体,调用子项的存储库并执行该特定子项中的 jpa 方法 repo 。
void findEntity(AbstractEntity entity) {
entity.setId(abstractEntityRepository.findOne(entity.getName())
.map(AbstractEntity::getId)
.orElseThrow(() -> new SomeException(entity.getName())));
}
这是我现在的服务,它确实可以像那样工作,但它很臃肿:
@Service
public class SomeService {
private final RealEntity1Repository realEntity1Repository;
private final RealEntity2Repository realEntity2Repository;
private final RealEntity3Repository realEntity3Repository ;
... 5 more times ..
public SomeService(RealEntity1Repository realEntity1Repository, RealEntity2Repository realEntity2Repository,
RealEntity3Repository realEntity3Repository,
... 5 more) {
this.realEntity1Repository = realEntity1Repository;
this.realEntity2Repository = realEntity2Repository;
this.realEntity3Repository = realEntity3Repository;
... 5 more
}
... some methods
void findRealEntity1(RealEntity1 entity) {
entity.setId(realEntity1Repository.findOne(entity.getName())
.map(RealEntity1::getId)
.orElseThrow(() -> new SomeException(entity.getName())));
}
void findRealEntity2(RealEntity2 entity) {
entity.setId(realEntity2Repository.findOne(entity.getName())
.map(RealEntity2::getId)
.orElseThrow(() -> new SomeException(entity.getName())));
}
...
更新
感谢 @Antoniosss 的提示,我解决了问题!
添加Optional<C> findByName(String name);
到 super 存储库
然后创建一个新服务来实现实体存储库特定的事务方法。在实现AbstractEntity和实体特定方法之间的映射时,在之前的服务中调用此服务:
public void mapAbstractEntity(AbstractEntity abstractEntity) {
if (abstractEntity instanceof RealEntity1 { // call RealEntity1 method from service}
else if (abstractEntity instanceof RealEntity2) { ... }
最佳答案
基于实际代码 - 您可以将 findByName
通用方法添加到抽象存储库,创建将实体类型映射到存储库的映射,然后使用 findRealEntity(AbstractEntity)
的单一实现这将选择正确的存储库并对其调用 findByName
。
关于java - 通过继承和类型参数化存储库访问 JPA 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60550782/