### Eclipse Workspace Patch 1.0
#P imap-trunk
Index: jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailbox.java
===================================================================
--- jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailbox.java	(revision 957939)
+++ jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailbox.java	(working copy)
@@ -19,6 +19,7 @@
 package org.apache.james.imap.jpa.mail.model;
 
 import javax.persistence.Basic;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
@@ -48,7 +49,7 @@
     @Id @GeneratedValue private long mailboxId;
     
     /** The value for the name field */
-    @Basic(optional=false) private String name;
+    @Basic(optional=false) @Column(unique = true)  private String name;
 
     /** The value for the uidValidity field */
     @Basic(optional=false) private long uidValidity;
Index: jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java
===================================================================
--- jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java	(revision 956027)
+++ jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java	(working copy)
@@ -98,11 +98,11 @@
     /**
      * Rollback is not supported by level 1 JCR implementations, so just do nothing
      */
-    protected void rollback() throws MailboxException {
+    protected void rollback(Exception e) throws MailboxException {
         try {
             // just refresh session and discard all pending changes
             getSession().refresh(false);
-        } catch (RepositoryException e) {
+        } catch (RepositoryException ex) {
             // just catch on rollback by now
         }
     }
Index: store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java
===================================================================
--- store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java	(revision 956027)
+++ store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java	(working copy)
@@ -38,7 +38,7 @@
             transaction.run();
             commit();
         } catch (MailboxException e) {
-            rollback();
+            rollback(e);
             throw e;
         }
     }
@@ -46,22 +46,22 @@
     /**
      * Begin transaction
      * 
-     * @throws StorageException
+     * @throws MailboxException
      */
     protected abstract void begin() throws MailboxException;
 
     /**
      * Commit transaction
      * 
-     * @throws StorageException
+     * @throws MailboxException
      */
     protected abstract void commit() throws MailboxException;
     
     /**
      * Rollback transaction
      * 
-     * @throws StorageException
+     * @throws MailboxException
      */
-    protected abstract void rollback() throws MailboxException;
+    protected abstract void rollback(Exception e) throws MailboxException;
 
 }
Index: jpa/src/main/java/org/apache/james/imap/jpa/JPATransactionalMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/imap/jpa/JPATransactionalMapper.java	(revision 956027)
+++ jpa/src/main/java/org/apache/james/imap/jpa/JPATransactionalMapper.java	(working copy)
@@ -76,11 +76,12 @@
         }
     }
 
+
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.transaction.AbstractTransactionalMapper#rollback()
+     * @see org.apache.james.imap.store.transaction.AbstractTransactionalMapper#rollback(java.lang.Exception)
      */
-    protected void rollback() throws MailboxException {
+    protected void rollback(Exception e) throws MailboxException {
         EntityTransaction transaction = entityManager.getTransaction();
         // check if we have a transaction to rollback
         if (transaction.isActive()) {
Index: jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java	(revision 957939)
+++ jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java	(working copy)
@@ -21,13 +21,17 @@
 
 import java.util.List;
 
+import javax.persistence.EntityExistsException;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.NoResultException;
 import javax.persistence.PersistenceException;
+import javax.persistence.RollbackException;
 
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.jpa.JPATransactionalMapper;
 import org.apache.james.imap.jpa.mail.model.JPAMailbox;
+import org.apache.james.imap.mailbox.MailboxException;
+import org.apache.james.imap.mailbox.MailboxExistsException;
 import org.apache.james.imap.mailbox.MailboxNotFoundException;
 import org.apache.james.imap.mailbox.StorageException;
 import org.apache.james.imap.store.mail.MailboxMapper;
@@ -40,6 +44,7 @@
 
     private static final char SQL_WILDCARD_CHAR = '%';
     private final char delimiter;
+    private String mailboxName;
     
     public JPAMailboxMapper(EntityManagerFactory entityManagerFactory, char delimiter) {
         super(entityManagerFactory);
@@ -47,11 +52,31 @@
     }
 
     /**
+     * Rollback and throw an {@link MailboxException} if the exception was caused by an unique key 
+     */
+    protected void rollback(Exception e) throws MailboxException {
+        try {
+            super.rollback(e);
+            if (e instanceof EntityExistsException)
+                throw new MailboxExistsException(mailboxName);
+        } catch (PersistenceException ex) {
+            if (ex instanceof RollbackException) {
+                Throwable t = e.getCause();
+                if (t != null && t instanceof EntityExistsException)
+                    throw new MailboxExistsException(mailboxName);
+            } 
+        } finally {
+            mailboxName = null;
+        }
+    }
+
+    /**
      * @see org.apache.james.imap.store.mail.MailboxMapper#save(Mailbox)
      */
     public void save(Mailbox<Long> mailbox) throws StorageException {
         try {
             getEntityManager().persist(mailbox);
+            this.mailboxName = mailbox.getName();
         } catch (PersistenceException e) {
             throw new StorageException(HumanReadableText.SAVE_FAILED, e);
         } 
