Results 1 to 7 of 7

Thread: Transactions: IllegalStateException

  1. #1
    Join Date
    Jun 2007
    Posts
    18

    Default Transactions: IllegalStateException

    Hello!

    I'm implementing an example program using a plain JDO DAO (like the one in the Spring Reference Manual). Unfortunately, I get an IllegalStateException: "No JDO PersistenceManager bound to thread, and configuration does not allow creation of non-transactional one here"

    The example is a simple command-line app:
    Code:
    public static void main(String[] args)
    {
      ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
      MyDao myDao = (MyDao) ctx.getBean("myDao");
      myDao.doSomething();
    }
    The DAO code looks like this:
    Code:
    public class MyDao
    {
    	private PersistenceManagerFactory pmf;
    
    	public MyDao(PersistenceManagerFactory pmf)
    	{
    		this.pmf = pmf;
    	}
    
    	public void doSomething()
    	{
    		PersistenceManager pm = pmf.getPersistenceManager();
    		//PersistenceManager pm = PersistenceManagerFactoryUtils.getPersistenceManager(pmf, false);
    	}
    }
    And this is my configuration:
    Code:
    <bean id="pmf" class="com.signsoft.ibo.client.PersistenceManagerFactoryImpl" destroy-method="close">
      </bean>
    
      <bean id="pmfProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
    	<property name="targetPersistenceManagerFactory" ref="pmf"/>
    	<property name="allowCreate" value="false"/>
      </bean>
    
      <bean id="myDao" class="MyDao">
    	<constructor-arg ref="pmfProxy"/>
      </bean>
    
      <bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
      	<property name="persistenceManagerFactory" ref="pmfProxy"/>
      </bean>
    
      <tx:advice id="txAdvice" transaction-manager="transactionManager">
      	<tx:attributes>
    		<tx:method name="*" propagation="REQUIRED"/>
    	</tx:attributes>
      </tx:advice>
    
      <aop:config>
      	<aop:pointcut id="serviceMethods" expression="execution(* MyDao.*(..))"/>
      	<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/>
      </aop:config>
    The Exception occurs regardless if I use "pmf.getPersistenceMangager()" or "PersistenceManagerFactoryUtils.getPersistenceMana ger(pmf, false)".

    I would prefer a DAO that does not have any Spring dependencies, though.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Please post your stacktrace...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Jun 2007
    Posts
    18

    Default

    Code:
    2007-06-05 12:00:17,546 [main] DEBUG support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'myDao'
    Exception in thread "main" java.lang.IllegalStateException: No JDO PersistenceManager bound to thread, and configuration does not allow crea
    tion of non-transactional one here
            at org.springframework.orm.jdo.PersistenceManagerFactoryUtils.doGetPersistenceManager(PersistenceManagerFactoryUtils.java:153)
            at org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy$TransactionAwareFactoryInvocationHandler.invoke(Transa
    ctionAwarePersistenceManagerFactoryProxy.java:149)
            at $Proxy0.getPersistenceManager(Unknown Source)
            at MyDao.doSomething(MyDao.java:17)
            at TransactionEx.main(TransactionEx.java:26)

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    It looks like as if your pointcut isn't matching. The method you call is directly called at the dao where as I would expect a $Proxy#.doSomething... By default the proxying used is interface based, so either enable class proxying or use an interface. From a design point of view I would go for the last option.

    Code:
    public interface MyDao {
      public void doSomething();
    }
    Dao

    Code:
    public class MyDaoImpl implements MyDao {
    	private PersistenceManagerFactory pmf;
    
    	public MyDao(PersistenceManagerFactory pmf) {
    		this.pmf = pmf;
    	}
    
    	public void doSomething() {
    		PersistenceManager pm = pmf.getPersistenceManager();
    		//PersistenceManager pm = PersistenceManagerFactoryUtils.getPersistenceManager(pmf, false);
    	}
    }
    configuration

    Code:
    <bean id="myDao" class="MyDaoImpl">
      <constructor-arg ref="pmfProxy"/>
    </bean>
    The rest can remain untouched.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Jun 2007
    Posts
    18

    Default

    Unfortunately it is still not working, although it seems that Spring is now trying to create a transaction:

    Code:
    2007-06-05 13:00:18,984 [main] DEBUG support.DefaultListableBeanFactory  - Returning cached instance of singleton bean 'myDao'
    2007-06-05 13:00:19,000 [main] DEBUG jdo.JdoTransactionManager  - Using transaction object [org.springframework.orm.jdo.JdoTransactionManage
    r$JdoTransactionObject@db4fa2]
    2007-06-05 13:00:19,000 [main] DEBUG jdo.JdoTransactionManager  - Creating new transaction with name [MyDao.doSomething]: PROPAGATION_REQUIR
    ED,ISOLATION_DEFAULT
    Exception in thread "main" org.springframework.transaction.CannotCreateTransactionException: Could not open JDO PersistenceManager for trans
    action; nested exception is java.lang.IllegalStateException: No JDO PersistenceManager bound to thread, and configuration does not allow cre
    ation of non-transactional one here
    Caused by: java.lang.IllegalStateException: No JDO PersistenceManager bound to thread, and configuration does not allow creation of non-tran
    sactional one here
            at org.springframework.orm.jdo.PersistenceManagerFactoryUtils.doGetPersistenceManager(PersistenceManagerFactoryUtils.java:153)
            at org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy$TransactionAwareFactoryInvocationHandler.invoke(Transa
    ctionAwarePersistenceManagerFactoryProxy.java:149)
            at $Proxy0.getPersistenceManager(Unknown Source)
            at org.springframework.orm.jdo.JdoTransactionManager.doBegin(JdoTransactionManager.java:318)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java
    :350)
            at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:2
    62)
            at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
            at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
            at $Proxy1.doSomething(Unknown Source)
            at TransactionEx.main(TransactionEx.java:26)

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    What is your reasoning behind 'allowCreate=false'? Won't this disable the creation of a new PersistenceManager in case none is found for the current thread? Which is the case with your test-case. You have a new thread, a new call is being made and now persistence manager can be found, however creation of a new one is also not allowed...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7
    Join Date
    Jun 2007
    Posts
    18

    Default

    AFAIK, the allowCreate property specifies if the PersistenceManagerFactory is allowed to create a non-transactional persistence manager, if no transactional persistence manager can be found.

    There is also a paragraph in the Spring Reference Manual (p. 232):
    With such DAOs that rely on active transactions, it is recommended to enforce active transactions through
    turning TransactionAwarePersistenceManagerFactoryProxy's "allowCreate" flag off:
    I want to make sure, that I have a transactional persistence manager when I execute my service methods, so I guess I have to set this property to 'false', or am I wrong here?

Posting Permissions

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