I would like to use Spring LDAP ODM and Spring LDAP Transaction frameworks together. Is this even recommended or doable?
When I try and use the frameworks together I get the following exception when a rollback is attempted:
Spring configuration:Code:org.springframework.ldap.NameAlreadyBoundException: [LDAP: error code 68 - Entry Already Exists]; nested exception is javax.naming.NameAlreadyBoundException: [LDAP: error code 68 - Entry Already Exists]; remaining name 'uid=testuser1,cn=users,o=division1,o=companyA' at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:171) at org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:810) at org.springframework.ldap.core.LdapTemplate.executeReadWrite(LdapTemplate.java:802) at org.springframework.ldap.core.LdapTemplate.rename(LdapTemplate.java:1171) at org.springframework.ldap.transaction.compensating.RebindOperationExecutor.performOperation(RebindOperationExecutor.java:116) at org.springframework.transaction.compensating.support.DefaultCompensatingTransactionOperationManager.performOperation(DefaultCompensatingTransactionOperationManager.java:69) at org.springframework.transaction.compensating.support.CompensatingTransactionUtils.performOperation(CompensatingTransactionUtils.java:63) at org.springframework.ldap.transaction.compensating.manager.TransactionAwareDirContextInvocationHandler.invoke(TransactionAwareDirContextInvocationHandler.java:87) at $Proxy15.rebind(Unknown Source) at org.springframework.ldap.core.LdapTemplate$27.executeWithContext(LdapTemplate.java:1143) at org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:807) at org.springframework.ldap.core.LdapTemplate.executeReadWrite(LdapTemplate.java:802) at org.springframework.ldap.core.LdapTemplate.rebind(LdapTemplate.java:1141) at org.springframework.ldap.core.LdapTemplate.rebind(LdapTemplate.java:1370) at org.springframework.ldap.odm.core.impl.OdmManagerImpl.update(OdmManagerImpl.java:194) at com.hoshooley.edu.ldap.ModifyPersonService.modify(ModifyPersonService.java:27) at com.hoshooley.edu.ldap.ModifyPersonService$$FastClassByCGLIB$$1553bfee.invoke(<generated>) at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621) at com.hoshooley.edu.ldap.ModifyPersonService$$EnhancerByCGLIB$$527973f2.modify(<generated>) at com.hoshooley.edu.ldap.dao.EbizPersonDaoImplTest.updateAndRollback(EbizPersonDaoImplTest.java:38)
ModifyPersonService:Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- DAO Beans --> <bean id="personDaoTarget" class="com.hoshooley.edu.ldap.dao.EbizPersonDaoImpl"> <property name="ldapTemplate" ref="ldapTemplate" /> <property name="authLdapTemplate" ref="authLdapTemplate" /> <property name="objectClassDefinition" ref="objectClassDef" /> </bean> <bean id="objectClassDef" class="com.hoshooley.edu.ldap.dao.ObjectClassDefinition"> <constructor-arg index="0" ref="authLdapTemplate" /> <constructor-arg index="1" value="ebizPerson" /> </bean> <bean id="odmManager" class="org.springframework.ldap.odm.core.impl.OdmManagerImplFactoryBean"> <property name="converterManager" ref="converterManager" /> <property name="contextSource" ref="contextSource" /> <property name="managedClasses"> <set> <value>com.hoshooley.edu.ldap.dao.EbizPersonDaoImpl</value> </set> </property> </bean> <!-- Ldap connection pooling *********************** See http://static.springsource.org/sprin...l/pooling.html for more details --> <bean id="contextSourcePool" class="org.springframework.ldap.pool.factory.PoolingContextSource"> <property name="contextSource" ref="contextSourceTarget" /> <property name="dirContextValidator" ref="dirContextValidator" /> <property name="testOnBorrow" value="true" /> <property name="testWhileIdle" value="true" /> </bean> <bean id="dirContextValidator" class="org.springframework.ldap.pool.validation.DefaultDirContextValidator" /> <bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="url" value="ldap://localhost:389" /> <property name="base" value="dc=education,dc=net" /> <property name="userDn" value="uid=service_admin,cn=users,o=services, dc=education,dc=net" /> <property name="password" value="" /> <property name="pooled" value="false" /> </bean> <!-- User Authentication context source definition ********************************************* Note: Do not pool this context as it is used for authentication --> <bean id="authenticatedContextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="url" value="ldap://localhost:389" /> <property name="base" value="dc=education,dc=net" /> <property name="userDn" value="uid=service_admin,cn=users,o=services, dc=education,dc=net" /> <property name="password" value="" /> <property name="pooled" value="false" /> <property name="dirObjectFactory"> <null /> </property> </bean> <bean id="authLdapTemplate" class="org.springframework.ldap.core.LdapTemplate"> <constructor-arg ref="authenticatedContextSourceTarget" /> </bean> <!-- Ldap transaction support ************************ See http://static.springsource.org/sprin...nsactions.html for more details --> <bean id="personDaoTarget" class="com.hoshooley.edu.ldap.ModifyPersonService"> <property name="odmManager" ref="odmManager" /> </bean> <bean id="contextSource" class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy"> <constructor-arg ref="contextSourcePool" /> </bean> <bean id="txManager" class="org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager"> <property name="contextSource" ref="contextSource" /> </bean> <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> <constructor-arg ref="contextSource" /> </bean> <tx:annotation-driven transaction-manager="txManager" /> <!-- TODO: Apply transaction to service class and not DOA --> <bean id="personDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="txManager" /> <property name="target" ref="personDaoTarget" /> <property name="transactionAttributes"> <props /> </property> </bean> </beans>
JUnit test:Code:package com.hoshooley.edu.ldap; import javax.annotation.Resource; import org.springframework.ldap.odm.core.OdmManager; import org.springframework.transaction.annotation.Transactional; import com.hoshooley.edu.ldap.dao.EbizPersonDaoImpl; public class ModifyPersonService { @Resource private OdmManager odmManager; public OdmManager getOdmManager() { return odmManager; } public void setOdmManager(OdmManager odmManager) { this.odmManager = odmManager; } @Transactional public EbizPersonDaoImpl modify(EbizPersonDaoImpl person) { person.setCompleteName("Updated complete name for " + person.getCompleteName()); odmManager.update(person); // This should fail as we have not set the appropriate request // control to modify operational attributes. person.setPwdReset(Boolean.TRUE); odmManager.update(person); // Return fresh instance of person return odmManager.read(EbizPersonDaoImpl.class, person.getDn()); } }
Code:package com.hoshooley.edu.ldap.dao; import static org.junit.Assert.assertNotNull; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.odm.core.OdmManager; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.hoshooley.edu.ldap.ModifyPersonService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/dao.xml"}) public class EbizPersonDaoImplTest { @Resource private OdmManager odmManager; @Resource ModifyPersonService modifyService; @Test public void updateAndRollback() throws Exception { EbizPersonDaoImpl ebizPerson = odmManager.read(EbizPersonDaoImpl.class, new DistinguishedName("uid=testuser1,cn=users,o=division1,o=companyA")); modifyService.modify(ebizPerson); } }


Reply With Quote
