h2. Deleting entries Deleting an entry is really easy. It's just a matter to know its *[DIRAPI:Dn]*. There is one important thing to understand though: if this entry has some children, it won't be deleted. h3. Simple Entry Deletion We can ask for deletion by providing the entry's *[DIRAPI:Dn]*, as in the following example : {code:java} @Test public void testDeleteLeafNode() throws Exception { assertTrue( session.exists( "cn=child1,cn=parent,ou=system" ) ); DeleteResponse response = connection.delete( "cn=child1,cn=parent,ou=system" ); assertNotNull( response ); assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() ); assertFalse( session.exists( "cn=child1,cn=parent,ou=system" ) ); } {code} Trying to delete the parent alone would lead to an error (NOT_ALLOWED_ON_NON_LEAF) : {code:java} @Test public void testDeleteNonLeafFailure() throws Exception { assertTrue( session.exists( "cn=parent,ou=system" ) ); DeleteResponse response = connection.delete( "cn=parent,ou=system" ); assertNotNull( response ); assertEquals( ResultCodeEnum.NOT_ALLOWED_ON_NON_LEAF, response.getLdapResult().getResultCode() ); assertTrue( session.exists( "cn=parent,ou=system" ) ); } {code} h3. Recursive Deletion of Entries Usually, you can't delete an entry and all of its children. However, some servers accept such a request if you send a delete request and a TreeDelete control. This control is a [draft|http://tools.ietf.org/html/draft-armijo-ldap-treedelete-02], which has been implemented by *Microsoft*, *OpenDS*, *OpenDJ*. It will delete all the children and the entry itself. We don't use a normal _delete()_ method, there is a specific method, _deleteTree()_ to accomplish the delete request in ApacheDS. Here is an example: {code:java} @Test public void testDeleteWithCascadeControl() throws Exception { assertTrue( session.exists( "cn=parent,ou=system" ) ); DeleteResponse response = connection.deleteTree( "cn=parent,ou=system" ); assertNotNull( response ); assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() ); assertFalse( session.exists( "cn=parent,ou=system" ) ); } {code} h3. Sending a DeleteRequest with a Control It's also possible to associate a *[DIRAPI:Control]* with the delete request. In order to do that you have to create a *[DIRAPI:DelRequest]* instance. In the following example, we will add the Delete Tree control (this makes this call equivalent to the _deleteTree()_ method). {code:java} @Test public void testDeleteWithControl() throws Exception { assertTrue( session.exists( "cn=parent,ou=system" ) ); if ( connection.isControlSupported( "1.2.840.113556.1.4.805" ) ) { DeleteRequest deleteRequest = new DeleteRequestImpl(); deleteRequest.setName( new Dn( "cn=parent,ou=system" ) ); Control deleteTreeControl = new OpaqueControl( "1.2.840.113556.1.4.805" ); deleteRequest.addControl( deleteTreeControl ); DeleteResponse deleteResponse = connection.delete( deleteRequest ); assertNotNull( deleteResponse ); assertEquals( ResultCodeEnum.SUCCESS, deleteResponse.getLdapResult().getResultCode() ); assertFalse( session.exists( "cn=parent,ou=system" ) ); } } {code} h3. Asynchronous Delete You can also decide to send an asynchronous delete request: the method will return a Future that you can check later. You have to construct a *[DIRAPI:DeleteRequest]* instance. Here is an example : {code:java} @Test public void testDeleteAsync() throws Exception { assertTrue( session.exists( "cn=child,cn=parent,ou=system" ) ); DeleteRequest deleteRequest = new DeleteRequestImpl(); deleteRequest.setName( new Dn( "cn=child,cn=parent,ou=system" ) ); DeleteFuture deleteFuture = connection.deleteAsync( deleteRequest ); DeleteResponse deleteResponse = deleteFuture.get( 1000, TimeUnit.MILLISECONDS ); assertNotNull( deleteResponse ); assertEquals( ResultCodeEnum.SUCCESS, deleteResponse.getLdapResult().getResultCode() ); assertFalse( session.exists( "cn=child,cn=parent,ou=system" ) ); } {code}