无法查找JNDI名称[jdbc / jbpm-ds]

问题描述 投票:0回答:2

我正在尝试开发jBPM春季启动应用程序,但无法找到JNDI名称[jdbc / jbpm-ds]错误。

为此,我使用了jbpm-7.36.0.Final,Spring-Boot-2.2.6和jbpm-spring-boot 7.36.0 Final以及Spring Boot Bitronix api。以下是我的pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jta-bitronix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <!-- <version>5.2.6.RELEASE</version> -->
    </dependency>
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>jbpm-spring-boot-starter-basic</artifactId>
        <version>${runtime.version}</version>
    </dependency>
</dependencies>

在我的application.properties文件中,我已配置了以下值

#hibernate configuration
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.hbm2ddl.auto=update

#JTA enabled
spring.jta.enabled=true

#bitronix Non-XA transaction manager configuration
spring.datasource.xa.properties.url=jdbc:sqlserver://10.1.5.209:1433;databaseName=MRR3;
spring.datasource.xa.properties.uniqueName=jdbc/jbpm-ds
spring.datasource.xa.properties.username=sa
spring.datasource.xa.properties.password=password_123
spring.datasource.xa.properties.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.xa.data-source-class-name=bitronix.tm.resource.jdbc.lrc.LrcXADataSource

下面是代码段

    @Bean
    public StatefulKnowledgeSession newStatefulKnowledgeSession() throws Exception {
        RuntimeEnvironmentBuilder builder = null;
        if (usePersistence) {
            TransactionManager tm = TransactionManagerServices.getTransactionManager();

            entityManagerFactory = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");//Line where Exception occurs
            System.out.println(entityManagerFactory.getProperties());

            Environment env = EnvironmentFactory.newEnvironment();
            env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
            env.set(EnvironmentName.TRANSACTION_MANAGER, tm);

            builder = RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
                    .entityManagerFactory(entityManagerFactory)
                    .addEnvironmentEntry(EnvironmentName.TRANSACTION_MANAGER, tm);

            builder.knowledgeBase(readKnowledgeBase);

            StatefulKnowledgeSession ksession = JPAKnowledgeService
                    .newStatefulKnowledgeSession(readKnowledgeBase, null, env);

            return ksession;
            // builder =
            // RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
            // .entityManagerFactory(entityManagerFactory);
        }
    }

共享重要的日志信息

2020-05-11 23:41:12.122  INFO 18852 --- [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: org.jbpm.persistence.jpa
    ...] {} <>
2020-05-11 23:41:12.155  WARN 18852 --- [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'newStatefulKnowledgeSession' defined in class path resource [com/citiustech/mrr/controller/AbstractionProcessController.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.kie.internal.runtime.StatefulKnowledgeSession]: Factory method 'newStatefulKnowledgeSession' threw exception; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] {} <>
.
.
.
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:179)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at com.citiustech.mrr.controller.AbstractionProcessController.newStatefulKnowledgeSession(AbstractionProcessController.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 20 common frames omitted
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [jdbc/jbpm-ds]
    at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:100)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:100)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    ... 39 common frames omitted
Caused by: javax.naming.NameNotFoundException: unable to find a bound object at name 'jdbc/jbpm-ds'
    at bitronix.tm.jndi.BitronixContext.lookup(BitronixContext.java:83)
    at bitronix.tm.jndi.BitronixContext.lookup(BitronixContext.java:67)
    at javax.naming.InitialContext.lookup(InitialContext.java:421)
    at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:97)
    ... 48 common frames omitted

我也想知道以下对我的理解是否正确

  1. jBPM仅支持JTA类型的事务,即全局事务。集成jBPM时不能使用RESOURCE_LOCAL事务类型。
  2. 当我说事务类型为RESOURCE_LOCAL时,意味着将在整个应用程序中共享一个数据源事务。
  3. jBPM RuntimeManager使用'org.jbpm.domain'持久单元名称(强制类型)来处理其所有内部表操作。
  4. 所有应用程序特定的事务都可以通过默认的持久性单元名称即'org.jbpm.persistence.jpa'进行处理。可以通过自定义持久性上下文来覆盖。
  5. JTA进一步分为XADatasource类型和Non-XADatasource类型两种。当数据源位于应用程序服务器容器中时,应使用XADatasource。 Non-XADatasource对于基于EJB的应用程序很有用。
  6. XADatasource在配置下需要

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />

  7. 非XADatasource,以下配置所需

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>

  8. 第6点或第7点是否必要,如果需要,如何不使用persistence.xml。

  9. 以下属性的用途是什么,什么罐子具有此类

    spring.jpa.properties.hibernate.transaction.manager_lookup_class = org.hibernate.transaction.BTMTransactionManagerLookup

java spring-boot jta bitronix redhat-bpm
2个回答
1
投票

有一些误解:

    正在使用
  • jbpm-spring-boot-starter-basic,但您没有使用任何弹簧加载的bean创建您的StatefulKnowledgeSession。 starter的主要思想是避免低级框架配置。
  • 此参数:spring.datasource.xa.properties.uniqueName未出现在文档中,并且是camelCase。

解决方案1:春季启动

使用正式版及其配置

#data source configuration
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.url=jdbc:h2:./target/spring-boot-jbpm;MVCC=true
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.type=org.apache.tomcat.jdbc.pool.XADataSource

#hibernate configuration
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

#transaction manager configuration
spring.jta.narayana.transaction-manager-id=1

如我们所见,jbpm-spring-boot-starter-basic依赖于spring-boot数据源引擎,而没有任何new数据库配置。为什么?因为StatefulKnowledgeSession只需要经典的数据库连接。

也许此启动程序使用@ Autowire初始化了一个StatefulKnowledgeSession准备在任何Spring Java bean中使用”

解决方案2:Spring +手动配置

简单的研究显示,从JPAKnowledgeService创建StatefulKnowledgeSession需要经典:

EntityManagerFactory和TransactionManager

  • https://github.com/kiegroup/droolsjbpm-knowledge/blob/master/kie-internal/src/main/java/org/kie/internal/persistence/jpa/JPAKnowledgeService.java
  • 也可以在您的代码中看到:

    Environment env = EnvironmentFactory.newEnvironment();
                env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
                env.set(EnvironmentName.TRANSACTION_MANAGER, tm);
    

    在此示例中:

    http://www.javased.com/index.php?source_dir=droolsjbpm-integration/drools-container/drools-spring/src/main/java/org/drools/container/spring/beans/StatefulKnowledgeSessionBeanFactory.java

    public static class JpaConfiguration {
      private EntityManagerFactory emf;
      private PlatformTransactionManager tm;
    }
    //..
    Environment env = KnowledgeBaseFactory.newEnvironment();
    env.set( EnvironmentName.ENTITY_MANAGER_FACTORY,
    jpaConfiguration.getEntityManagerFactory() );
    env.set( EnvironmentName.TRANSACTION_MANAGER,
    jpaConfiguration.getPlatformTransactionManager() );
    

    所以解决方案可能只是将弹簧靴配置为具有优雅的自动接线:

    //@SpringBootApplication or @Configuration
    public class SpringMainApplication{
      @Autowire
      private EntityManagerFactory emf;
      @Autowire
      private PlatformTransactionManager tm;
      @Autowire
      private KnowledgeBase kbase;
    
      @Bean
      public KnowledgeBase readKnowledgeBase() throws Exception {
        List<RuleResource> resources = new ArrayList<RuleResource>();
        resources.add(new RuleResource("zzz/explore/ruleengine/rules/CalcPI.drl", ResourceType.DRL));
        return KnowledgeBaseHelper.readKnowledgeBase(resources);
      }
    
      @Bean
      public StatefulKnowledgeSession newStatefulKnowledgeSession() throws Exception {
        //if KnowledgeBase autowire does not works, just call directly
        //KnowledgeBase kbase =  readKnowledgeBase();
        Environment env = KnowledgeBaseFactory.newEnvironment();
        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
        env.set( EnvironmentName.TRANSACTION_MANAGER,tm);
    
        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
        return ksession;
      }
    
    }
    

    现在,我们需要配置spring boot以便准备使用该实例:

    @Autowire
    private EntityManagerFactory emf;
    @Autowire
    private PlatformTransactionManager tm;
    

    我们可以使用:

    //@SpringBootApplication or @Configuration
    class SpringMainApplication {
    
      //spring boo twill auto-provide a Bean of type DataSource
      // if the properties are there
      @Autowired
        private DataSource dataSource;
    
      @Bean
      public EntityManagerFactory entityManagerFactory() {
    
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
    
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.acme.domain");
        factory.setDataSource(dataSource);
        factory.afterPropertiesSet();
    
        return factory.getObject();
      }
    
      @Bean
      public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
      }
    }
    

    [创建大量EntityManagerFactory和TransactionManager的文档和示例很多。检查参考部分。

    如果适当使用启动器,也许也不需要此配置

    解决方案3:手动创建实例

    如您所见,仅需要一个entitymanager和transactionmanager。同样,要创建一个entitymanager,需要一个有效的数据源。因此,您只需要类似以下内容:

    //@SpringBootApplication or @Configuration
    public class SpringMainApplication{
    
      @Bean
      public KnowledgeBase readKnowledgeBase() throws Exception {
        List<RuleResource> resources = new ArrayList<RuleResource>();
        resources.add(new RuleResource("zzz/explore/ruleengine/rules/CalcPI.drl", ResourceType.DRL));
        return KnowledgeBaseHelper.readKnowledgeBase(resources);
      }
    
      @Bean
      public StatefulKnowledgeSession newStatefulKnowledgeSession() throws Exception {
    
        //Crete datasource
        //https://gist.github.com/jrichardsz/8b8dffcf1cdf42444654abc227d9f4c1
        //or use the spring provided datasource
    
        //create an entity manger
        EntityManagerFactory emf = ...;
        //create an transaction manger
        PlatformTransactionManager tm =....;
    
        Environment env = KnowledgeBaseFactory.newEnvironment();
        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
        env.set( EnvironmentName.TRANSACTION_MANAGER,tm);
    
        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
        return ksession;
      }
    
    }
    

    }

    注意
    • 这些片段未经测试,因为流口水且数据库不易于配置,并且您没有共享一个最小的可运行示例。

  • 我将添加此研究的http链接

  • 参考

  • create datasource
  • create datasource
  • autowire datasource
  • configure entitymanager and transaction manager
  • configure entitymanager and transaction manager
  • create knowledgebase
  • create knowledgebase
  • create knowledgebase
  • JPAKnowledgeService
  • JPAKnowledgeService
  • JPAKnowledgeService
  • JPAKnowledgeService
  • JPAKnowledgeService
  • JPAKnowledgeService
  • spring boot starters
  • spring boot starters
  • StatefulKnowledgeSession
  • StatefulKnowledgeSession

  • 0
    投票

    根据@JRichardsz的建议,我对代码进行了以下更改以使其与Spring Boot兼容

    © www.soinside.com 2019 - 2024. All rights reserved.