Java 在Camel中使用动态JPA端点有什么缺点吗?

Java 在Camel中使用动态JPA端点有什么缺点吗?,java,hibernate,jpa,apache-camel,Java,Hibernate,Jpa,Apache Camel,上下文 我一直在尝试使用Camel(v2.23.0)和Hibernate(v5.3.7)为我的应用程序创建一个通用的持久层。我还使用HikariCP作为连接池。为了实现这个通用持久性层,我使用Camel JPA组件构建核心持久性路由,如下所示: from("direct:getEntityById") .toD("jpa:${header.entityClassName}?persistenceUnit=" + projec

上下文

我一直在尝试使用Camel(v2.23.0)和Hibernate(v5.3.7)为我的应用程序创建一个通用的持久层。我还使用HikariCP作为连接池。为了实现这个通用持久性层,我使用Camel JPA组件构建核心持久性路由,如下所示:

from("direct:getEntityById")
                .toD("jpa:${header.entityClassName}?persistenceUnit=" + projectStage.toString() +
                        "&namedQuery=${header.entityClassSimpleName}.${header.queryName}");

from("direct:upsertEntity")
                .toD("jpa:${header.entityClassName}?usePersist=false&persistenceUnit=" + projectStage.toString());
    ...
    public <T> Optional<T> getEntityById(Object id, String queryName, Class<T> clazz) throws GenericDAOException {
        try {
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put("id", id);
            List<T> entities = (List<T>) fluentProducerTemplate
                    .withHeader("id", id)
                    .withHeader("entityClassName", clazz.getName())
                    .withHeader("entityClassSimpleName", clazz.getSimpleName())
                    .withHeader("queryName", queryName)
                    .withHeader("CamelJpaParameters", queryParams)
                    .to("direct:getEntityById")
                    .request(List.class);

            ...
        }
        ...
    }

    @Override
    public <T> void upsertEntity(T entityObject) throws GenericDAOException  {
        try {
            fluentProducerTemplate
                    .withBody(entityObject)
                    .withHeader("entityClassName", entityObject.getClass().getName())
                    .to("direct:upsertEntity")
                    .request();
        }
        ...
    }
在DAO中,我使用了一个动态JPA端点,因此我可以为任何JPA实体重用路由

我通过一个普通的Java DAO类调用这些路由,如下所示:

from("direct:getEntityById")
                .toD("jpa:${header.entityClassName}?persistenceUnit=" + projectStage.toString() +
                        "&namedQuery=${header.entityClassSimpleName}.${header.queryName}");

from("direct:upsertEntity")
                .toD("jpa:${header.entityClassName}?usePersist=false&persistenceUnit=" + projectStage.toString());
    ...
    public <T> Optional<T> getEntityById(Object id, String queryName, Class<T> clazz) throws GenericDAOException {
        try {
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put("id", id);
            List<T> entities = (List<T>) fluentProducerTemplate
                    .withHeader("id", id)
                    .withHeader("entityClassName", clazz.getName())
                    .withHeader("entityClassSimpleName", clazz.getSimpleName())
                    .withHeader("queryName", queryName)
                    .withHeader("CamelJpaParameters", queryParams)
                    .to("direct:getEntityById")
                    .request(List.class);

            ...
        }
        ...
    }

    @Override
    public <T> void upsertEntity(T entityObject) throws GenericDAOException  {
        try {
            fluentProducerTemplate
                    .withBody(entityObject)
                    .withHeader("entityClassName", entityObject.getClass().getName())
                    .to("direct:upsertEntity")
                    .request();
        }
        ...
    }
问题:

根据以下文档:,我们应该避免由于过度的资源消耗而创建无穷无尽的动态端点。因为我使用的是JPA组件,所以我特别关注创建的DB连接的数量,如果不在某个阈值内,可能会导致应用程序失败

为了解决这些潜在问题,我使用了一个连接池。由于所有JPA端点都将使用相同的EntityManagerFactory,因此我假定连接池也将在这些端点之间共享

因此,我有以下问题:

  • JPA路由何时会释放DB连接?(如中所示,它们是在JPA路由完成消息处理后立即发布的,还是连接与JPA端点的生命周期相关联?)

  • 是否会为每个唯一的URI创建一个新的动态JPA端点

  • 在使用动态JPA端点时,我还需要注意哪些潜在问题?(我想内存消耗是其中之一)


  • Camel是一个EIP工具包,所以在您试图实现的目标和Camel的用途方面确实存在不匹配。