Announcement Announcement Module
Collapse
No announcement yet.
Ldap ODM and Transaction support Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Ldap ODM and Transaction support

    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:

    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)
    Spring configuration:
    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>
    ModifyPersonService:
    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());
    	}
    }
    JUnit test:
    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);
    	}
    }

  • #2
    you can refer to: http://www.jayxu.com/2012/04/17/13449/

    Comment

    Working...
    X