java - Maven接口(interface)方法之间的模糊引用

标签 java maven jpa repository

我有一个使用 EclipseLink 的具有 JPA 持久性的 Java Spring 项目。我想为我的实体使用 JpaRepository 接口(interface),并在大多数情况下使用默认实现,但我还需要定义一些我自己的方法,有时我需要重写默认方法,如保存。

我的代码在 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;
}

当我将它编译为在 Tomcat 上运行时,它在 Eclipse 中运行良好。对象 ReportRepository reportRepository 具有来自 JPA 存储库实现的方法和我的自定义方法,当我调用 reportRepository.save(...) 时调用自定义保存方法。但是,当我执行 Maven Install 时,编译器会提示引用不明确:

[ERROR] /C:/Users/Jarno/git/Korjaamotestiraportointi/src/main/java/fi/testcenter/service/ReportService.java:[40,40] reference to save is ambiguous both method save(fi.testcenter.domain.report.Report) in fi.testcenter.repository.ReportRepositoryCustom and method save(S) in org.springframework.data.repository.CrudRepository match

我发现对我的存储库进行编码有点复杂。我想为 JPA 存储库使用现成的实现,而不必编写任何额外的代码。我的代码使一切保持整洁。在服务中用作引用的存储库接口(interface)以相同的方式命名,每个实体和方法也以相同的方式命名,任何自定义方法或覆盖都是通过自定义接口(interface)和实现完成的。我不需要在任何地方编写任何不必要的代码。但后来我遇到了 Maven 的问题。

我首先在 Eclipse Tomcat 服务器上运行 Maven,成功地编译了我的代码。但是,如果我执行 Maven Clean,然后执行 Maven Install,我会收到一堆错误。显然,我不想在使用 Maven 进行编译时诉诸任何形式的技巧。

那么是否有一个修复程序允许使用 Maven 执行此操作?还是有另一种编码方式来编写我在这里要执行的操作?

最佳答案

因此,经过大量谷歌搜索等等,似乎无法为 Maven 的编译器定义哪个保存方法是主要的,JpaRepository 中的那个还是我的自定义存储库中的那个。我不知道 Eclipse 使用的编译器是如何做到的,但显然 Maven 在这里不遵循相同的逻辑。真可惜,因为这种编写自定义方法并覆盖某些 JpaRepository 方法的方式将是最干净、最好的方式。如果存在多个候选对象,则有一个 @Primary 注释用于确定哪个 bean 是 Autowiring 的主要 bean,但似乎没有针对接口(interface)实现方法的等效解决方案。我还没有找到任何其他不需要编写任何额外代码的方法。扩展 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]
}

这不是一个完美的解决方案,因为我必须包括我在我的接口(interface)及其实现中使用的默认方法,只需调用标准的 JpaRepository 方法。但它有效,而且我的 ReportRepository 接口(interface)的使用很干净,因为我没有自定义方法的自定义名称,如 customSave(),但实现的细节隐藏在实现类中。

如果有人有更好的解决方案,而且代码量最少,我很想听听。

关于java - Maven接口(interface)方法之间的模糊引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46992424/

相关文章:

java - 如何在 Ant 脚本中调用 Maven 目标?

java - 在 MySQL 中维护来自大型连续数据源的预处理数据

java - NoClassDefFoundError : : org. apache.log4j.Logger

java - 如何安装STS到eclipseoxy(2018.march) 市场上没有sts?

Java - 如何从ArrayList打印某个对象的方法?

java - 如何将不同方案的两个事务合并为一个?

Maven 将依赖组设置为特定版本

Maven站点+搜索能力

spring - JPA @Entity 内的 Bean 注入(inject)

java - 加载具有不存在子实体的实体时 JPA 预期的行为