Results 1 to 8 of 8

Thread: JdoDaoSupport requires it's wrapped in a transaction?

  1. #1
    Join Date
    Aug 2004
    Location
    Denver
    Posts
    249

    Default JdoDaoSupport requires it's wrapped in a transaction?

    I started using JdoDaoSupport today and found that I have to use transactions or things fail with a "transaction not active" message. With all of the other DaoSupport classes, I was able to declare transactions on my service objects rather than on DAOs. Is it a requirement that JdoDaoSupport children be wrapped like the following?

    I'm using JPOX 1.0.2.

    Code:
        <!-- UserDAO for JDO -->
        <bean id="userDAO" 
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager"><ref local="transactionManager"/></property>
            <property name="target">
                <bean class="org.appfuse.dao.jdo.UserDAOJdo" autowire="byName"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>
    Thanks,

    Matt

  2. #2
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    No, in fact it's still best form to wrap your service objects with transactions, and not the JdoDaoSupport-based DAOs.

    I'm confused thouugh, are you trying to run this with no transaction at all, or with a transaction around the service insteaf of around the dao? Where transactions come in is that if there is a wrapping transaction, a PersistenceManager instance will be synchronized to and associated with that transaction (either via JdoTransactionManager or JdoInterceptor, or via the first use of a JdoTemplate with the allowCreate flag set to true), but the latter certainly doesn't care at what scope the transaction exists.

    Can you provide a stack trace?

    Colin
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

  3. #3
    Join Date
    Aug 2004
    Location
    Denver
    Posts
    249

    Default

    I'm basically trying to do what I've done with the Hibernate, Spring JDBC and iBATIS SupportDaos. I usually just declare a DAO, set it's dataSource, sessionFactory, persistenceManager or whatever it may be and then run with it. When I test these DAOs, there is no transactions declared on them.

    I tried to do the following with JDO:

    Code:
    	<bean id="persistenceManagerFactory" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
    		<property name="jdoProperties">
    			<props>
    				<prop key="javax.jdo.PersistenceManagerFactoryClass">org.jpox.PersistenceManagerFactoryImpl</prop>
    				<prop key="javax.jdo.option.ConnectionDriverName">com.mysql.jdbc.Driver</prop>
    				<prop key="javax.jdo.option.ConnectionUserName">root</prop>
    				<prop key="javax.jdo.option.ConnectionPassword"></prop>
    				<prop key="javax.jdo.option.ConnectionURL">jdbc&#58;mysql&#58;//localhost/appfuse</prop>
    				<prop key="org.jpox.autoCreateSchema">true</prop>
    				<prop key="org.jpox.validateTables">false</prop>
    				<prop key="org.jpox.validationConstraints">false</prop>
    			</props>
    		</property>
    	</bean>
    
        <bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
    		<property name="persistenceManagerFactory"><ref bean="persistenceManagerFactory"/></property>
    	</bean>
    
        <bean id="userDAO" class="org.appfuse.dao.jdo.UserDAOJdo">
    		<property name="persistenceManagerFactory"><ref bean="persistenceManagerFactory"/></property>
    	</bean>
    But when I run my simple DAOTest, I get:

    Code:
        &#91;junit&#93; Testcase&#58; testGetUsers&#40;org.appfuse.dao.UserDAOTest&#41;&#58;        Caused an ERROR
        &#91;junit&#93; Transaction is not active; nested exception is org.jpox.exceptions.TransactionNotActiveE
    xception&#58; Transaction is not active
        &#91;junit&#93; org.springframework.orm.jdo.JdoUsageException&#58; Transaction is not active; nested excepti
    on is org.jpox.exceptions.TransactionNotActiveException&#58; Transaction is not active
        &#91;junit&#93; org.jpox.exceptions.TransactionNotActiveException&#58; Transaction is not active
        &#91;junit&#93;     at org.jpox.AbstractPersistenceManager.assertActiveTransaction&#40;AbstractPersistenceMa
    nager.java&#58;334&#41;
        &#91;junit&#93;     at org.jpox.AbstractPersistenceManager.makePersistent&#40;AbstractPersistenceManager.jav
    a&#58;797&#41;
        &#91;junit&#93;     at org.springframework.orm.jdo.JdoTemplate$7.doInJdo&#40;JdoTemplate.java&#58;217&#41;
        &#91;junit&#93;     at org.springframework.orm.jdo.JdoTemplate.execute&#40;JdoTemplate.java&#58;136&#41;
        &#91;junit&#93;     at org.springframework.orm.jdo.JdoTemplate.makePersistent&#40;JdoTemplate.java&#58;215&#41;
        &#91;junit&#93;     at org.appfuse.dao.jdo.UserDAOJdo.saveUser&#40;UserDAOJdo.java&#58;26&#41;
        &#91;junit&#93;     at org.appfuse.dao.UserDAOTest.testGetUsers&#40;UserDAOTest.java&#58;30&#41;
        &#91;junit&#93;     at sun.reflect.NativeMethodAccessorImpl.invoke0&#40;Native Method&#41;
        &#91;junit&#93;     at sun.reflect.NativeMethodAccessorImpl.invoke&#40;NativeMethodAccessorImpl.java&#58;39&#41;
        &#91;junit&#93;     at sun.reflect.DelegatingMethodAccessorImpl.invoke&#40;DelegatingMethodAccessorImpl.java
    &#58;25&#41;

  4. #4
    Join Date
    Aug 2004
    Location
    New York, USA
    Posts
    6

    Default Re: JdoDaoSupport requires it's wrapped in a transaction?

    Quote Originally Posted by mraible
    Is it a requirement that JdoDaoSupport children be wrapped like the following?

    Code:
        <!-- UserDAO for JDO -->
        <bean id="userDAO" 
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager"><ref local="transactionManager"/></property>
            <property name="target">
                <bean class="org.appfuse.dao.jdo.UserDAOJdo" autowire="byName"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>
    If you take a look at the Kodo-Spring sample app, with KODO JDO they don't declare TX semantics on the DAO, only on Service POJO's. However, they use the ProxyFactoryBean + TransactionInterceptor approach, rather than the simpler TransactionProxyFactoryBean approach. Is there any difference between these 2 approaches?

  5. #5
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Matt is saying that he doesn't want to wrap transactionally at all.

    I don't have the JDO spect handy, and it's been a while since I've written production code with JDO (Kodo, in my case), which was always transactional anyways, but I'm about 100% sure that support for nontransactional (including persistent-nontransactional) states in JDO 1.0 is optional. So JPOX throwing an error when there is no transaciton is probably a JPOX implementation specific thing as opposed to a JDO specific thing.

    Personally, what I do for my Mapper/DAO tests is wrap the code inside a programmatic TransactionTemplate, using a TransactionManager and other beans coming from an appcontext specific (or at least one of the xml fragments) specific to that test. This allows usage and testing of multiple DAOs working together, or multiple calls into the same DAO to do sequential operations, used in the same fashion inside one encompassing transaction, as they would be in real-life code.

    Regards,
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

  6. #6
    Join Date
    Aug 2004
    Location
    Denver
    Posts
    249

    Default

    Yeah, I looked at the Kodo-Spring example, and as far as I can tell, if there's a call to "makePersistent()" in a class - then that class has to be wrapped in a transaction. Of all the DAOs in the example, CategoryDAOImpl is the only one with a makePersistent() call and it's got a transaction interceptor defined in the Spring context file.

    Maybe JdoTemplate should be enhanced to create a new transaction if one doesn't exist?

    This would make testing easier. Also, it would be nice if the JDO support was more in-line w/ the other persistence frameworks (JDBC, Hibernate, iBATIS, OJB) - where a transaction is not required on the DAO.

  7. #7
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    No, I really don't think it's the job of a template object to get involved in crreating transactions. It can ensure that stuff that needs to get synchronized with and bound to an existing tx gets done so, but it would not be consistent if JdoTemplate did this. W/regards to making it more in-line with the other persistence frameworks, I think this would actually make it less in-line with how the templates for the other persistence frameworks behave. But more to the point, it doesn't make sense for the template to create transactions because transactions should span the service layer, not individual DAOs.

    Again, this is a JPOX issue as far as I can tell, but I don't frankly really see it as an issue. In real life usage of a DAO you use a transaction, so it's actually cleaner or closer to that real-life usage to also test the DAO inside a transaction.
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

  8. #8

    Default

    Quote Originally Posted by Colin Sampaleanu
    Matt is saying that he doesn't want to wrap transactionally at all.

    I don't have the JDO spec handy, and it's been a while since I've written production code with JDO (Kodo, in my case), which was always transactional anyways, but I'm about 100% sure that support for nontransactional (including persistent-nontransactional) states in JDO 1.0 is optional. So JPOX throwing an error when there is no transaciton is probably a JPOX implementation specific thing as opposed to a JDO specific thing.
    Hi guys,

    javax.jdo.option.NontransactionalRead
    javax.jdo.option.NontransactionalWrite
    are both optional in JDO 1.0. JPOX does support NontransactionalRead though we have fixed a couple of bugs in that area in the last few days (but neither bug responsible for throwing TransactionNotActive exceptions). The fact is though, to use a JDO implementation without transactions you would need to set the NontransactionalRead property to "true".

    I'd guess that you need to add this to your "jdoProperties" if you want to run without transactions [if you look at the springjdo example for Kodo, you'll find this property being set in the jdoProperties section]
    -Andy
    DataNucleus - Standardised persistence, multiple datastores

Similar Threads

  1. Unit testing with JOTM and JtaTransactionManager
    By lalle in forum Architecture
    Replies: 1
    Last Post: Oct 15th, 2005, 09:05 AM
  2. Replies: 0
    Last Post: Jun 6th, 2005, 06:22 AM
  3. Replies: 3
    Last Post: May 16th, 2005, 07:04 AM
  4. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM
  5. Transaction pb Hibernate/MySQL
    By syluser in forum Data
    Replies: 2
    Last Post: Aug 28th, 2004, 02:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •