我更喜欢使用通过LocalContainerEntityManagerfactorybean获得的JPA Entitymanager工厂进行持久化.
但是,当我想支持spring ldap和JPA之间的事务时,我碰壁了.我的服务层同时调用LDAP dao和JPA dao.
春天的ldap具有ContextSourceAndHibernateTransactionManager,它需要sessionFactory
而且它没有ContextSourceAndJPATransactionManager
当我将ContextSourceAndDataSourceTransactionManager与为LocalContainerEntityManagerfactorybean配置的相同数据源一起使用时,它甚至不保留记录!
我不确定是否可以使用JTATransactionManager,因为LDAP不支持XA.
我的临时解决方案是在DAO层上使用JPATransactionManager并在服务层上使用LDAPTransactionManager.并确保在服务层中最后一个调用JPA DAO.
如果您愿意,我可以提供代码片段.
谢谢
最佳答案
spring-ldap-1.3.1 documentation的6.3点告诉使用
ContextSourceAndDataSourceTransactionManager,用于“ jdbc-ldap” tx目的. spring-ldap-core-1.3.1还具有ContextSourceAndHibernateTransactionManager.
ContextSourceAndDataSourceTransactionManager,用于“ jdbc-ldap” tx目的. spring-ldap-core-1.3.1还具有ContextSourceAndHibernateTransactionManager.
展望这两个,一个人可以轻松创建自己的
ContextSourceAndJpaTransactionManager
并将其配置为
<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"/>
玩得开心!
ps.我差点忘了
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.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.getSuspendedResources())
);
ldapManagerDelegate.doRollback(new DefaultTransactionStatus(
actualTransactionObject.getLdapTransactionObject(),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.getSuspendedResources())
);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。