Bitronix + Spring + Hibernate + Persistence

天大地大妈咪最大 提交于 2019-12-06 06:25:53

Your persistence provider does its lookups on jndi. Data sources defined in Spring application context are not bound to jndi. Hence, persistence provider's lookup attempt for the data source fails as there is no such data source bound to jndi.

You may want to check http://forum.springsource.org/showthread.php?t=13984.

Can you try defining your data sources in the server context and looking them up in your spring application by their jndi names?

Looks like your datasource hasn't been created yet when Persistence.createEntityManagerFactory() is called. Since your bitronixTransactionManager bean depends on the dataSource one, you should see some INFO log telling you BTM has started which should mean the datasource has been created too.

Another potential reason could be that Hibernate doesn't lookup the datasource in the right JNDI context. You could enable bitronix.tm.jndi DEBUG logs to assert that its JNDI provider is getting called.

What could be the problem?

Are you able to consume this data source in a standalone java app, by asking for jdbc/testDS1? In regular Tomcat DataSources, you'd need to ask for java:comp/env/jdbc/testDS1, not only jdbc/testDS1.

How does Hibernate persistence knows to refer to spring txManager bean?

It doesn't. You are saying this to Hibernate:

        <property name="hibernate.transaction.manager_lookup_class"
            value="org.hibernate.transaction.BTMTransactionManagerLookup" />

So, Hibernate will use the lookup class to, well, "lookup" the transaction manager :-)

Are you deploying this as a WAR or EAR? Did you declare the data source in your web.xml and set it up on the app server?

UPDATE: Since you've declared the data source in your WAR, make sure you've set up the JNDI data source in Tomcat.

Your error says: "Caused by: org.hibernate.HibernateException: Could not find datasource: jdbc/testDS1". That's a JNDI lookup name.

So where does "I don't want to" fit into this?

Spring needs a Java Naming and Directory service to look up the data source associated with this name; that's what Tomcat provides. If not Tomcat, where do you propose that Spring get it from? The naming service is part of the Java EE app server.

You either have to set up the JNDI data source and connection pool on Tomcat OR forego the benefits it provides and tell Spring to use a DriverManagerDataSource instead:

http://static.springsource.org/spring/docs/2.5.x/reference/jdbc.html

I believe I've got a similar scenario running. My persistence.xml is like the following:

<persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <!-- other configuration ommited -->
    <jta-data-source>java:comp/env/jdbc/YourPersistentUnitJNDI_Name</jta-data-source>
    <!-- other configuration ommited -->
</persistence-unit>

And the spring application bean xml file is like:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="myPersistenceUnit" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>

Hope that helps!

I think either is the persistence.xml has not been configered correctly or you have not start up the SPring container. here I post my persistence.xml code

enter code here
<persistence-unit name="org.drools.task" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/mysql</jta-data-source>
    <class>org.drools.task.Attachment</class>
<properties>
        <property name="hibernate.archive.autodetection" value="class"/>
        <property name="hibernate.current_session_context_class" value="jta" />
        <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
        <property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
        <property name="hibernate.show_sql" value="true" />

        <!-- after first run the application, should comment it, else it will drop and create table each time 
        <property name="hibernate.hbm2ddl.auto" value="create" /> -->
</properties>
</persistence-unit>

and my testing code:

enter code here
    ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");
    JtaTransactionManager txManager = (JtaTransactionManager) ctx.getBean("txManager");
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    TransactionStatus status = txManager.getTransaction(def);
    System.out.println("The transaction manager is "+txManager);
    System.out.println("The transaction is "+status);

the transaction manager config is same as you posted. it can work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!