【发布时间】:2020-03-05 17:16:16
【问题描述】:
假设我有一个抽象实体
@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())));
}
我只想有一个方法调用,如下面的伪代码(我知道不能实例化抽象类),它将实体作为参数的抽象实体,调用孩子的 repo 并在该特定孩子中执行 jpa 方法回购。
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); 添加到 SuperRepository
然后创建一个实现实体存储库特定事务方法的新服务。在实现 AbstractEntity 与实体特定方法之间的映射时,在上一个服务中调用此服务:
public void mapAbstractEntity(AbstractEntity abstractEntity) {
if (abstractEntity instanceof RealEntity1 { // call RealEntity1 method from service}
else if (abstractEntity instanceof RealEntity2) { ... }
【问题讨论】:
-
eeee 为什么不使用
findById??..... -
我没有 id,我通过 Example.Matcher 搜索名称
-
这个名字是不是到处都是
name? -
是的,到处都是这样命名的
-
findByName然后。
标签: java inheritance spring-data-jpa