Announcement Announcement Module
Collapse
No announcement yet.
Transactions: IllegalStateException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Please post your stacktrace...

    Comment


    • #3
      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)

      Comment


      • #4
        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.

        Comment


        • #5
          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)

          Comment


          • #6
            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...

            Comment


            • #7
              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?

              Comment

              Working...
              X