接口方法之间的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做到这一点?或者还有另一种编码方式,我想在这里做什么?

+0

[Spring JPA CrudRepsoitory类已经有save方法](https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html#save- S-),为什么用相同的签名定义你自己的? –

+0

@Sagar Rohankar重写默认方法,因为在将实体保存到数据库之前,我需要做某些事情。我不想以不同的方式命名该方法,并且必须记住,对于某些实体,我需要调用除保存以外的名称的自定义方法。 – hubbabubba

+0

则不会在ReportRepository接口中扩展ReportRepositoryCustom。 –

因此,经过大量的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()这样的自定义方法的自定义名称,但实现的细节隐藏在实现类中。

如果任何人有更好的解决方案,只有最少量的代码,我会有兴趣听到它。