Announcement Announcement Module
Collapse
No announcement yet.
Spring 2.5 + JPA + Hibernate = No Transactions? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 2.5 + JPA + Hibernate = No Transactions?

    Hi All,

    I'm a recent Spring convert---I've been using EJB for years and Spring's lightweight approach seems like just the thing for my project. In the past I've been able to use JPA with Session Beans and Entity Beans and transaction management and everything has been great.

    However, I've been killing myself trying to figure out how to get Spring to manage my transactions. Basically, I want to inject an entity manager instance (just like I'm used to) and mark methods as @Transactional when they need a new transaction.

    I've had absolutely no luck getting that to work however and for the meantime I've resorted to manual transaction management via the Entity Manager Factory / Entity Manager.


    Here's what I've got so far:

    persistence.xml

    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="MyPU" transaction-type="RESOURCE_LOCAL">
        <class>foo.Client</class>
    </persistence-unit>
    </persistence>
    applicationContext.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:jee="http://www.springframework.org/schema/jee"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/jee
           http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
    
    
        <context:annotation-config />
        <context:component-scan base-package="foo"/>
    
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="MyPU"/>
            <property name="dataSource" ref="dataSource"/>
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
            </property>
        </bean>
    
        <tx:annotation-driven  transaction-manager="transactionManager"/>
    
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
    
        <bean id="propertyConfigurer"
              class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
              p:location="/WEB-INF/jdbc.properties" />
    
        <bean id="dataSource"
              class="org.springframework.jdbc.datasource.DriverManagerDataSource"
              p:driverClassName="com.mysql.jdbc.Driver"
              p:url="jdbc:mysql://127.0.0.1:9999/XXX"
              p:username="XXX"
              p:password="XXX" />
    
    </beans>

    An example object It'd like to be able to use:

    Code:
    @Service("fooDAO")
    public class FooDAO {
    
    
        @PersistenceContext
        private EntityManager em;
    
        @Transactional
        public void doStuff()
        {
            Client c = em.find(Client.class, "foo");
    
            em.remove(c);
    
        }
    
    }

    However, when I deploy this to GlassfishV3, I get the following error:

    Code:
    java.lang.RuntimeException: The persistence-context-ref-name [foo.FooDAO/em] in module [XXX] resolves to a persistence unit called [MyPU] which is of type RESOURCE_LOCAL. Only persistence units with transaction type JTA can be used as a container managed entity manager. Please verify your application.
            at com.sun.enterprise.deployment.BundleDescriptor.findReferencedPUsViaPCRefs(BundleDescriptor.java:686)
            at com.sun.enterprise.deployment.WebBundleDescriptor.findReferencedPUs(WebBundleDescriptor.java:999)
            at org.glassfish.persistence.jpa.JPADeployer.prepare(JPADeployer.java:103)
            at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:644)
            at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:296)
            at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:183)
            at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:272)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:305)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:320)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1176)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$900(CommandRunnerImpl.java:83)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
            at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1224)
            at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:365)
            at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:204)
            at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:166)
            at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:100)
            at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:245)
            at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
            at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
            at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
            at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
            at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
            at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
            at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
            at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
            at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
            at java.lang.Thread.run(Thread.java:637)

    What am I doing wrong? Is there any hope of getting this going? Or am I back to manual transaction land?

    I've tried other things, like setting the transaction manager to JtaTransactionManager with the Glassfish JNDI reference, but to no avail. For example:


    Code:
      <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
            <!-- <property name="entityManagerFactory" ref="entityManagerFactory"/> -->
            <property name="transactionManagerName" value="java:appserver/TransactionManager"/>

  • #2
    I suggest the search as similair, as not the same, question has been answered before.

    You don't program to interfaces so y ou need class proxies.

    1) Make sure cglib is in your classpath
    2) tell tx:annotation-driven to use classproxies.

    Comment

    Working...
    X