Datanucleus: moving from @Transactional to non-transactional

落爺英雄遲暮 提交于 2019-12-11 04:07:13

问题


I am using Datanucleus, JDO and Spring's declarative @Transactional management woven with Aspect-J.

But when a 'normal' method gets a persistent object from a @Transactional method, the object's state will become transient (the persistence manager seems to be removed) and the object is no longer persistent.

Example:

public class Example {

    public void test() throws Exception {
       Login l = getLogin();                          
       JDOHelper.getObjectState(l);              // transient instead of persistent
       l.getSomeOtherPersistentObj().doStuff();  // NullpointerException :(
    }

    @Transactional
    private Login getLogin() {
        // do transactional stuff here
        // ..
        return dao.find(Login.class, 1);
    }
}

Why is this and how can I fix it without adding @Transactional in places where transactions are not needed? The following does (obviously) work so this indicates that a transactional as well as a non-transactional connection can be made:

  • A @Transactional method calls a @Transactional method
  • A @Transactional method calls a normal method
  • A normal method calls a normal method

If I call dao.refresh(l), I get: 'Object with id "" is managed by a different Object Manager', so maybe Spring is working on a different persistence manager than the DAO, is this the cause?

Here's my spring configuration (it might be relevant):

<bean id="pmf" class="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" destroy-method="close">
  <property name="connectionDriverName" value="com.mysql.jdbc.Driver"/>
  ...
  <constructor-arg>
    <map>
      <entry key="datanucleus.autoCreateSchema" value="true" />
    </map>
  </constructor-arg>
</bean>
<bean id="myPmfProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
  <property name="targetPersistenceManagerFactory" ref="pmf" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
  <property name="persistenceManagerFactory" ref="myPmfProxy" /> 
</bean>
<bean id="JDODao" class="sw.JDODao">
  <property name="persistenceManagerFactory" ref="myPmfProxy" /> 
</bean>

回答1:


It turned out that my objects need to be detachable to do this.

Iv'e added (detachable="true") to my @PersistenceCapable annotations and set the following datanucleus options:

<entry key="datanucleus.DetachAllOnCommit" value="true" />
<entry key="datanucleus.detachedState" value="all" />


来源:https://stackoverflow.com/questions/7354101/datanucleus-moving-from-transactional-to-non-transactional

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