2012-03-26 14 views
3

Ich bevorzuge die Verwendung von JPA Entitymanager factory über LocalContainerEntityManagerFactoryBean für die Persistenz. Aber ich stoße an die Wand, wenn ich Transaktion zwischen Frühling ldap und JPA unterstützen möchte. Meine Service-Schicht ruft sowohl LDAP Dao als auch JPA Dao auf. Spring ldap hat ContextSourceAndHibernateTransactionManager erfordert SessionFactory und es ContextSourceAndJPATransactionManager nicht Wenn ich ContextSourceAndDataSourceTransactionManager mit der gleichen Datenquelle für LocalContainerEntityManagerFactoryBean konfiguriert ist, hält es nicht einmal einen Datensatz!So führen Sie Spring LDAP- und JPA-Transaktionen durch

Ich bin mir nicht sicher, ob ich JTATransactionManager verwenden kann, da LDAP nicht XA-fähig ist.

Meine vorläufige Lösung ist, JPATransactionManager auf DAO-Ebene zu verwenden und LDAPTransactionManager auf Serviceebene zu verwenden. Und stellen Sie sicher, dass JPA DAO in der Serviceebene zuletzt aufgerufen wird.

Ich kann Codefragmente bereitstellen, wenn Sie möchten. Dank

+1

Bitte geben Sie die Frage. –

+0

Ich versuche eine verteilte Transaktion zwischen Spring LDAP und Database durchzuführen, auf die über JPA zugegriffen wird – nir

Antwort

3

Punkt 6.3 von spring-ldap-1.3.1 documentation sagt ContextSourceAndDataSourceTransactionManager zu verwenden für 'jdbc-and-ldap' tx Zwecke. spring-ldap-core-1.3.1 hat auch einen ContextSourceAndHibernateTransactionManager.

Blick auf diese beiden, man kann seine eigene ContextSourceAndJpaTransactionManager einfach erstellen und konfigurieren Sie es als

<bean id="jpaUnderLdapTransactionManager" class="org.springframework.ldap.transaction.compensating.manager.ContextSourceAndJpaTransactionManager"> 
    <property name="contextSource" ref="ldapSimpleContextSource"/> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

<tx:annotation-driven transaction-manager="jpaUnderLdapTransactionManager"/> 

Spaß haben!

p.s. Ich habe fast vergessen

public class ContextSourceAndJpaTransactionManager extends JpaTransactionManager 
{ 

private static final long serialVersionUID = 1L; 

private ContextSourceTransactionManagerDelegate ldapManagerDelegate = 
     new ContextSourceTransactionManagerDelegate(); 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#isExistingTransaction(Object) 
*/ 
protected boolean isExistingTransaction(Object transaction) 
{ 
    ContextSourceAndJpaTransactionObject actualTransactionObject = 
      (ContextSourceAndJpaTransactionObject) transaction; 

    return super.isExistingTransaction(actualTransactionObject 
               .getJpaTransactionObject()); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doGetTransaction() 
*/ 
protected Object doGetTransaction() throws TransactionException 
{ 
    Object dataSourceTransactionObject = super.doGetTransaction(); 
    Object contextSourceTransactionObject = 
      ldapManagerDelegate.doGetTransaction(); 

    return new ContextSourceAndJpaTransactionObject(
      contextSourceTransactionObject, dataSourceTransactionObject 
    ); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doBegin(java.lang.Object, 
*  org.springframework.transaction.TransactionDefinition) 
*/ 
protected void doBegin(Object transaction, TransactionDefinition definition) 
     throws TransactionException 
{ 
    ContextSourceAndJpaTransactionObject actualTransactionObject = 
      (ContextSourceAndJpaTransactionObject) transaction; 

    super.doBegin(actualTransactionObject.getJpaTransactionObject(), 
        definition); 
    ldapManagerDelegate.doBegin(
      actualTransactionObject.getLdapTransactionObject(), 
      definition 
    ); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doCleanupAfterCompletion(java.lang.Object) 
*/ 
protected void doCleanupAfterCompletion(Object transaction) 
{ 
    ContextSourceAndJpaTransactionObject actualTransactionObject = 
      (ContextSourceAndJpaTransactionObject) transaction; 

    super.doCleanupAfterCompletion(actualTransactionObject 
              .getJpaTransactionObject()); 
    ldapManagerDelegate.doCleanupAfterCompletion(actualTransactionObject 
               .getLdapTransactionObject()); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doCommit(org.springframework.transaction.support.DefaultTransactionStatus) 
*/ 
protected void doCommit(DefaultTransactionStatus status) 
     throws TransactionException 
{ 

    ContextSourceAndJpaTransactionObject actualTransactionObject = 
      (ContextSourceAndJpaTransactionObject) status.getTransaction(); 

    try 
    { 
     super.doCommit(new DefaultTransactionStatus(
       actualTransactionObject.getJpaTransactionObject(), 
       status.isNewTransaction(), 
       status.isNewSynchronization(), 
       status.isReadOnly(), 
       status.isDebug(), 
       status.getSuspendedResources()) 
     ); 
    } 
    catch (TransactionException ex) 
    { 
     if (isRollbackOnCommitFailure()) 
     { 
      logger.debug("Failed to commit db resource, rethrowing", ex); 
      // If we are to rollback on commit failure, just rethrow the 
      // exception - this will cause a rollback to be performed on 
      // both resources. 
      throw ex; 
     } 
     else 
     { 
      logger.warn(
        "Failed to commit and resource is rollbackOnCommit not set -" 
          + " proceeding to commit ldap resource."); 
     } 
    } 
    ldapManagerDelegate.doCommit(new DefaultTransactionStatus(
      actualTransactionObject.getLdapTransactionObject(), 
      status.isNewTransaction(), 
      status.isNewSynchronization(), 
      status.isReadOnly(), 
      status.isDebug(), 
      status.getSuspendedResources()) 
    ); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doRollback(org.springframework.transaction.support.DefaultTransactionStatus) 
*/ 
protected void doRollback(DefaultTransactionStatus status) throws TransactionException 
{ 
    ContextSourceAndJpaTransactionObject actualTransactionObject = 
      (ContextSourceAndJpaTransactionObject) status.getTransaction(); 

    super.doRollback(new DefaultTransactionStatus(
      actualTransactionObject.getJpaTransactionObject(), 
      status.isNewTransaction(), 
      status.isNewSynchronization(), 
      status.isReadOnly(), 
      status.isDebug(), 
      status.getSuspendedResources()) 
    ); 
    ldapManagerDelegate.doRollback(new DefaultTransactionStatus(
      actualTransactionObject.getLdapTransactionObject(), 
      status.isNewTransaction(), 
      status.isNewSynchronization(), 
      status.isReadOnly(), 
      status.isDebug(), 
      status.getSuspendedResources()) 
    ); 
} 

@SuppressWarnings("UnusedDeclaration") 
public ContextSource getContextSource() 
{ 
    return ldapManagerDelegate.getContextSource(); 
} 

public void setContextSource(ContextSource contextSource) 
{ 
    ldapManagerDelegate.setContextSource(contextSource); 
} 

@SuppressWarnings("UnusedDeclaration") 
protected void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy) 
{ 
    ldapManagerDelegate.setRenamingStrategy(renamingStrategy); 
} 

private final static class ContextSourceAndJpaTransactionObject 
{ 
    private Object ldapTransactionObject; 

    private Object jpaTransactionObject; 

    public ContextSourceAndJpaTransactionObject(
      Object ldapTransactionObject, Object jpaTransactionObject) 
    { 
     this.ldapTransactionObject = ldapTransactionObject; 
     this.jpaTransactionObject = jpaTransactionObject; 
    } 

    public Object getJpaTransactionObject() 
    { 
     return jpaTransactionObject; 
    } 

    public Object getLdapTransactionObject() 
    { 
     return ldapTransactionObject; 
    } 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doSuspend(java.lang.Object) 
*/ 
protected Object doSuspend(Object transaction) throws TransactionException 
{ 
    throw new TransactionSuspensionNotSupportedException(
      "Transaction manager [" + getClass().getName() 
        + "] does not support transaction suspension"); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doResume(java.lang.Object, java.lang.Object) 
*/ 
protected void doResume(Object transaction, Object suspendedResources) 
     throws TransactionException 
{ 
    throw new TransactionSuspensionNotSupportedException(
      "Transaction manager [" + getClass().getName() 
        + "] does not support transaction suspension"); 
} 

/** 
* @see org.springframework.orm.jpa.JpaTransactionManager#doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus) 
*/ 
@Override 
protected void doSetRollbackOnly(DefaultTransactionStatus status) 
{ 
    super.doSetRollbackOnly(
      new DefaultTransactionStatus(
       ((ContextSourceAndJpaTransactionObject)status.getTransaction()) 
         .getJpaTransactionObject(), 
       status.isNewTransaction(), 
       status.isNewSynchronization(), 
       status.isReadOnly(), 
       status.isDebug(), 
       status.getSuspendedResources()) 

    ); 
} 
} 
Verwandte Themen