Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 你能在OSGi环境(比如Karaf)中使用Hibernate 5.2无状态会话而不使用JTA吗?_Java_Hibernate_Osgi_Jta_Karaf - Fatal编程技术网

Java 你能在OSGi环境(比如Karaf)中使用Hibernate 5.2无状态会话而不使用JTA吗?

Java 你能在OSGi环境(比如Karaf)中使用Hibernate 5.2无状态会话而不使用JTA吗?,java,hibernate,osgi,jta,karaf,Java,Hibernate,Osgi,Jta,Karaf,我试图使用无状态会话在OSGi环境(Karaf 4.0.7)中进行一些批量插入,但当我尝试提交事务时,我得到了 be.ikan.lib.orm.base.exceptions.PersistenceBrokerException: org.hibernate.TransactionException: Cannot retrieve the TransactionManager OSGi service! at be.ikan.lib.orm.hibernate.broker.Hibernate

我试图使用无状态会话在OSGi环境(Karaf 4.0.7)中进行一些批量插入,但当我尝试提交事务时,我得到了

be.ikan.lib.orm.base.exceptions.PersistenceBrokerException: org.hibernate.TransactionException: Cannot retrieve the TransactionManager OSGi service!
at be.ikan.lib.orm.hibernate.broker.HibernateStatelessPersistenceBrokerImpl.commitTransaction(HibernateStatelessPersistenceBrokerImpl.java:118)[79:be.ikan.lib.orm:7.0.0]
at be.ikan.scm4all.business.server.bs.pack.PackageServiceImpl.createLevelRequestFileRevisionAssociations(PackageServiceImpl.java:1412)[72:be.ikan.scm4all.daemons.server:5.8.0]
at be.ikan.scm4all.phases.core.level.LinkFileRevisionsPhase.execute(LinkFileRevisionsPhase.java:99)[72:be.ikan.scm4all.daemons.server:5.8.0]
at Proxy5a8c2944_a0d5_4e21_a1b7_3f30296f5993.execute(Unknown Source)[:]
at be.ikan.scm4all.phases.impl.DefaultPhaseExecutionImpl.execute(DefaultPhaseExecutionImpl.java:152)[114:be.ikan.scm4all.daemons.shared:5.8.0]
at be.ikan.scm4all.daemons.server.monitor.MonitorThread.run(MonitorThread.java:231)[72:be.ikan.scm4all.daemons.server:5.8.0]
Caused by: org.hibernate.TransactionException: Cannot retrieve the TransactionManager OSGi service!
at org.hibernate.osgi.OsgiJtaPlatform.retrieveTransactionManager(OsgiJtaPlatform.java:51)[62:org.hibernate.osgi:5.2.17.Final]
at org.hibernate.osgi.OsgiJtaPlatform.getCurrentStatus(OsgiJtaPlatform.java:98)[62:org.hibernate.osgi:5.2.17.Final]
at org.hibernate.internal.StatelessSessionImpl.flushBeforeTransactionCompletion(StatelessSessionImpl.java:667)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.internal.StatelessSessionImpl.beforeTransactionCompletion(StatelessSessionImpl.java:644)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:156)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)[60:org.hibernate.core:5.2.17.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)[60:org.hibernate.core:5.2.17.Final]
at be.ikan.lib.orm.hibernate.broker.HibernateStatelessPersistenceBrokerImpl.commitTransaction(HibernateStatelessPersistenceBrokerImpl.java:114)[79:be.ikan.lib.orm:7.0.0]
... 5 more
Caused by: org.hibernate.TransactionException: Cannot retrieve the TransactionManager OSGi service!
at org.hibernate.osgi.OsgiJtaPlatform.retrieveTransactionManager(OsgiJtaPlatform.java:46)[62:org.hibernate.osgi:5.2.17.Final]
我不使用JTA来管理事务,而是设置hibernate.transaction.coordinator\u class=jdbc。 使用常规session的代码运行良好。应用程序的另一部分在非OSGi环境中运行,无状态会话在那里工作正常

我追踪到Hibernate源代码,并在org.Hibernate.internal.StatelessSessionImpl中找到:

@Override
public void flushBeforeTransactionCompletion() {
    boolean flush = false;
    try {
        flush = (
                !isClosed()
                        && !isFlushModeNever()
                        && !JtaStatusHelper.isRollback(
                        getJtaPlatform().getCurrentStatus()
                ) );
    }
    catch (SystemException se) {
        throw new HibernateException( "could not determine transaction status in beforeCompletion()", se );
    }
    if ( flush ) {
        managedFlush();
    }
}
由于会话未关闭,且无状态SessionImpl.isFlushModeNever()始终返回false,因此始终会调用方法getJtaPlatform(),该方法最终失败,因为它可以找到一个JtaPlatform(org.hibernate.osgi.OsgiJtaPlatform),但未对其进行配置(因为我不使用它)

那么,这是否意味着如果不配置JTA,就不能使用无状态会话

我正在使用Hibernate 5.2.17。顺便说一下,这种方法在Hibernate 4.3.7中工作得很好,但是没有Hibernate osgi捆绑包,而且无状态SessionImpl类似乎经历了一些重大变化


经过进一步的调查,我通过安装Karaf特性“transaction”成功地使它工作。在karaf控制台中,我执行了
功能:install transaction
。这将安装一个OSGi事务管理器(由ApacheAries提供),它为javax.Transaction.TransactionManager注册一个服务实现,允许org.hibernate.OSGi.OsgiJtaPlatform类找到它并消除上述异常。 代码似乎在这之后工作:事务提交时没有问题,数据被持久化

但我仍然有一个问题:无状态会话是否使用JTA事务

在Tomcat中运行的应用程序的非OSGi部分,我在调试日志中找到了它

2018-08-29 13:29:00,615 [localhost-startStop-1] DEBUG JtaPlatformInitiator - No JtaPlatform was specified, checking resolver
2018-08-29 13:29:00,617 [localhost-startStop-1] DEBUG JtaPlatformResolverInitiator - No JtaPlatformResolver was specified, using default [org.hibernate.engine.transaction.jta.platform.internal.StandardJtaPlatformResolver]
2018-08-29 13:29:00,629 [localhost-startStop-1] DEBUG StandardJtaPlatformResolver - Could not resolve JtaPlatform, using default [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
因此,Hibernate使用org.Hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform

在karaf日志中,我找到了用于实例化SessionFactory的属性:

2018-08-29 14:45:48,897 | DEBUG | e: pid=[server]) | SessionFactoryImpl               | 72 - org.jboss.logging.jboss-logging - 3.3.1.Final | Building session factory
2018-08-29 14:45:48,936 | DEBUG | e: pid=[server]) | SessionFactoryImpl               | 72 - org.jboss.logging.jboss-logging - 3.3.1.Final | Session factory constructed with filter configurations : {}
2018-08-29 14:45:48,937 | DEBUG | e: pid=[server]) | SessionFactoryImpl               | 72 - org.jboss.logging.jboss-logging - 3.3.1.Final | Instantiating session factory with properties: {<a lot of properties>, hibernate.transaction.jta.platform=org.hibernate.osgi.OsgiJtaPlatform@7d6ea302, <more properties>}
2018-08-29 14:45:48,969 | DEBUG | e: pid=[server]) | SessionFactoryImpl               | 72 - org.jboss.logging.jboss-logging - 3.3.1.Final | Instantiated session factory
但这没有效果:它仍然记录了会话工厂是使用OsgiJtaPlatform创建的


如果我能以某种方式配置Hibernate,使其使用Karaf中的NoJtaPlatform,那么我想我就不需要额外的“事务”特性了。这也会让我相信应用程序只使用JDBC事务,而不是JTA。

我看待事物的方式。为了获得非JTA事务,您需要说服Hibernate它不在支持JTA的环境中。这意味着不启用JDBC不启用JMS不启用事务

下面是正在发生的事情>

  • 休眠视图。从hibernate的角度来看,“org.hibernate.engine.transaction.spi.TransactionFactory”决定了它在什么样的环境中使用,并根据环境初始化基于JDBC或基于JTA的事务管理器。本文件可在第2.2章和后续参考文献中阅读

  • 根据文件第4.16.4点的规定

  • ApacheKaraf提供容器管理的事务,如 OSGi服务

    下一句话是

    但是,已安装事务功能(作为可传递的 依赖关系)在安装企业功能(如jdbc或jms)时 功能(例如)

    这基本上意味着一旦启用JDBC服务,您将获得一个JTA transactio manager

    另一方面,由于您试图使用无状态HibernateSession,我的假设是您试图实现性能。友好的建议:)

  • 确保在读取Think@BatchSize时一次获取多个集合
  • 在生成ID时,确保序列具有良好的分配大小
  • 确保已将jdbc批处理大小配置为良好值
  • 确保您与Fetch之间存在延迟关系。选择
  • 忘了无状态会话:)您可能会惊讶于单凭hibernate就可以挤出这么多性能

    hibernate.transaction.jta.platform=org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform