接口方法之间的Maven模糊引用
我有一个使用EclipseLink的JPA持久性的Java Spring项目。我想为我的实体使用JpaRepository接口,并且在大多数情况下使用默认实现,但我也需要定义一些我自己的方法,并且有时需要覆盖像保存这样的默认方法。接口方法之间的Maven模糊引用
我的代码在Eclipse中编译时工作正常,但在使用Maven编译时,我不断收到模糊的引用错误。
我所做的就是这个(例如覆盖保存,因为我需要做某些事情的实体将被保存):
public interface ReportRepository extends JpaRepository<Report, Long>, ReportRepositoryCustom {
}
public interface ReportRepositoryCustom {
public Report save(Report report);
public int getReportCountForImporter(Long importerId);
...
}
public class ReportRepositoryCustomImplementation implements ReportRepositoryCustom {
public Report save(Report report) { ... }
public int getReportCountForImporter(Long importerId) { ... }
}
public class ReportService {
@Autowired
private ReportRepository reportRepository;
}
当我编译它来运行这个工程在Eclipse罚款Tomcat的。对象ReportRepository reportRepository具有来自JPA存储库实现和我的自定义方法的方法,并且在调用reportRepository.save(...)时调用自定义保存方法。然而,当我做Maven的安装时,编译器会抱怨不明确的引用:
[ERROR] /C:/用户/亚诺/ GIT中/ Korjaamotestiraportointi/SRC /主/爪哇/ FI/TestCenter的/服务/ ReportService.java:[40,40] 保存的引用在方法 中保存(fi.testcenter.domain.report.Report) fi.testcenter.repository.ReportRepositoryCustom和方法保存(S) in org.springframework .data.repository.CrudRepository匹配
我发现编码我的仓库有点复杂。我想为JPA存储库使用现成的实现,而不必额外编写任何代码。我的代码保持一切都很干净。在服务中用作参考的存储库接口对于每个实体的命名方式相同,并且方法也被命名为相同,并且任何自定义方法或覆盖均通过自定义接口和实现完成。我不需要在任何地方写任何不必要的代码。但后来我遇到了Maven的问题。
我已经设法用Maven编译我的代码,首先在Eclipse Tomcat服务器上运行它。但是,如果我做Maven Clean然后Maven Install,我会遇到一些错误。很显然,我不想在Maven编译时使用任何形式的黑客攻击。
那么是否有修复,可以用Maven做到这一点?或者还有另一种编码方式,我想在这里做什么?
因此,经过大量的Google搜索等等,似乎不可能为Maven的编译器定义哪些保存方法是主要的,JpaRepository中的还是我自定义存储库中的。我不知道Eclipse使用的编译器是如何做的,但显然Maven在这里并不遵循相同的逻辑。这很遗憾,因为这种对自定义方法进行编码并覆盖一些JpaRepository方法的方式将是最干净和最好的方法。如果存在多个候选项,则有一个@Primary注释用于确定哪个bean是主要用于自动装配的,但似乎没有对接口实现方法的等效解决方案。我还没有找到任何其他方式来做这件事,我不需要编写任何额外的代码。扩展SimpleJpaRepository类似乎是一个有点难看的解决方案,因为我必须确保实现被用作JpaRepository实现。
所以我决定用一种直接的方式来解决这个问题:
public interface ReportRepository {
public List<Report> findAll();
public Report findOne(Long id);
public void delete(Report report);
public Report save(Report report) throws OptimisticLockException;
public Long getReportCountForImporter(Long importerId);
.... [other custom methods]
}
public interface ReportRepositoryDefaultMethods extends JpaRepository<Report, Long> {
}
public class ReportRepositoryImpl implements ReportRepository {
@PersistenceContext()
EntityManager entityManager;
@Autowired
ReportRepositoryDefaultMethods reportRepositoryDefaultMethods;
public List<Report> findAll() {
return reportRepositoryDefaultMethods.findAll();
}
public Report findOne(Long id) {
return reportRepositoryDefaultMethods.findOne(id);
}
public void delete(Report report) {
reportRepositoryDefaultMethods.delete(report);
}
@Transactional
public Report save(Report report) throws OptimisticLockException {
[custom implementation using entityManager methods]
}
.... [other custom methods]
}
这不是一个整洁的解决方案,因为我必须包括我在接口使用默认的方法和其执行情况,只是调用到标准的JpaRepository方法。但它的工作原理和我的ReportRepository接口的使用是干净的,因为我没有像customSave()这样的自定义方法的自定义名称,但实现的细节隐藏在实现类中。
如果任何人有更好的解决方案,只有最少量的代码,我会有兴趣听到它。
[Spring JPA CrudRepsoitory类已经有save方法](https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html#save- S-),为什么用相同的签名定义你自己的? –
@Sagar Rohankar重写默认方法,因为在将实体保存到数据库之前,我需要做某些事情。我不想以不同的方式命名该方法,并且必须记住,对于某些实体,我需要调用除保存以外的名称的自定义方法。 – hubbabubba
则不会在ReportRepository接口中扩展ReportRepositoryCustom。 –