是否使用适合于验证JPA实现的Java断言



我正在开发一个具有(几乎)普通Java EE 6堆栈(EJB、JPA、JSF等)的应用程序。我们在Glassfish 3上托管我们的应用程序,目前与持久性相关的代码是100%纯JPA。

不幸的是,我们的应用程序的一部分必须使用Oracle10g数据库中的存储过程。为了调用这个存储过程,我们决定使用EclipseLink(与Glassfish捆绑在一起的JPA实现)。

由于我们代码的一小部分现在依赖于EclipseLink,我想知道如何验证这种依赖性。依赖项没有与应用程序打包,但假设它在我们的部署平台(即Glassfish)上可用。

在我看来,我们的选择是:

  1. 什么都不要做,就让它失败吧。我认为这个解决方案是次优的,因为它从未明确表示我们的代码假设存在EclipseLink
  2. 在if语句中检查EclipseLink并引发特定异常。

    if (!JpaHelper.isEclipseLink(entityManager)) {
        throw new InvalidJpaImplementationException();
    }
    
  3. 添加一个用于检查EclipseLink的断言,并让它在失败时抛出异常。

    assert JpaHelper.isEclipseLink(entityManager)) : "Blah!";
    

断言(选项3)是有效的解决方案吗?你喜欢另一种解决方案吗?哪一个,为什么

由于您使用的是JPA,我不会使实现EclipseLink特定(因为它必须符合JPA规范)。人们不应该关心他们使用的是什么JPA提供者。

如果您决定转移到(比方说)Hibernate(如果您实现依赖性验证),您的代码可能会中断。JPA规范的全部目的是,开发人员根本不应该担心实现供应商的产品。


如果您想使用EclipseLink的存储过程,那么我建议您创建一个引擎来调用存储过程,而不考虑EntityManager。这样,它仍然不会担心JPA实现提供程序的依赖性。可以在这里找到如何使用Hibernate JPA调用StoredProcedure的示例。

断言可以被禁用,这会在出现错误时破坏代码。因此,官方最好不要断言。如果将来其他实体管理器被删除,您最好删除测试,而不是禁用断言。原因:您很幸运,其他JPA使用了另一个实现。也许只为InvalidJpaImplementationException进行日志记录也更简单。

最新更新