Hi, I posted a mail about this problem before.

But I want to let you know and evaluate my patch.

To use db naive autoincrement, we use SequenceManagerNativeImpl and 
SequenceManagerMySQLImpl with access="readonly".

But, in this way, auto incremented value can be modified when you do
'store, delete, store'.

This is caused like below
------------------------------------------------------
// a.getId() == 0;  
broker.store(a);

// a.getId() is setted;
int aId = a.getId()

// check restore value.
a.equals(A.restoreByID(aId));

broker.delete(a);

broker.store(a);
// a.getId() != aId;  other value, autoincremented one;
------------------------------------------------------

This effect make treating foreign key harder wrong.
1:1 relation can be broken.

This is not usual stuation. But, This is not the same behavior as 
SequenceManagerHighLowImpl.

To fix this, SequenceManage has to update auto increment field only when
auto incremented by DB. the value must be changed when inserted.

Please try my patch for MySQLImpl. Though that implementation is ad-hoc.
It behaves like HighLowImpl.
 
-- shivaken
antshell: Ant command line front end
http://www.antshell.org
--- SequenceManagerMySQLImpl.java	2003-07-24 19:04:56.000000000 +0900
+++ SequenceManagerMySQLImpl.java.new	2003-07-24 16:23:13.000000000 +0900
@@ -176,38 +176,58 @@
     public void afterStore(JdbcAccess dbAccess, ClassDescriptor cld, Object obj) throws SequenceManagerException
     {
 
-        FieldDescriptor fd = cld.getAutoIncrementField();
-        if(fd != null)
-		{ // an autoinc column exists
-			ResultSetAndStatement rsStmt = null;
-            try
-            {
-				rsStmt = dbAccess.executeSQL("SELECT LAST_INSERT_ID() as newid FROM " + cld.getFullTableName(), cld, Query.NOT_SCROLLABLE);
-                int newid = 0;
-                if (rsStmt.m_rs.next())
-                {
-                    newid = rsStmt.m_rs.getInt("newid");
-                }
-                rsStmt.m_rs.close();
-                if(log.isDebugEnabled()) log.debug("After store - newid=" + newid);
+        /*
+          now Just for int field.
+         */
+        /*
+          autoincremented, means inserted, not updated.
+         */
 
-                PersistentField pf = fd.getPersistentField();
-                pf.set(obj, new Integer(newid));
-            }
-            catch (PersistenceBrokerException e)
+        FieldDescriptor fd = cld.getAutoIncrementField(); 
+        if ((fd != null)  && (isAutoIncremented(obj, fd)))
+        {
+            fd.getPersistentField().set(obj, new Integer(getNewId(dbAccess, cld)));
+        }     
+    }
+
+    private boolean isAutoIncremented(Object obj, FieldDescriptor fd) throws SequenceManagerException {
+
+        Object value = fd.getPersistentField().get(obj);  
+        return (value.equals(getUniqueValue(fd)));
+
+        // If so, value must be autoincremented.
+        // SequenceManageMySQLImpl getUniqueValue( int filed ) returns 0
+        // SequenceManageNativeImpl getUniqueValue( int filed ) returns -1
+    }
+
+    private int getNewId(JdbcAccess dbAccess, ClassDescriptor cld)
+    throws SequenceManagerException {
+        ResultSetAndStatement rsStmt = null;
+        int newid = 0;
+        try
+        {
+            rsStmt = dbAccess.executeSQL("SELECT LAST_INSERT_ID() as newid FROM " + cld.getFullTableName(), cld, Query.NOT_SCROLLABLE);
+            if (rsStmt.m_rs.next())
             {
-				throw new SequenceManagerException(e);
+                newid = rsStmt.m_rs.getInt("newid");
             }
-            catch (SQLException e)
-            {
-                throw new SequenceManagerException(e);
+            rsStmt.m_rs.close();
+            if(log.isDebugEnabled()) log.debug("After store - newid=" + newid);
+                    
             }
-			finally
-			{
-				rsStmt.close();
-			}
+        catch (PersistenceBrokerException e)
+        {
+            throw new SequenceManagerException(e);
         }
-
+        catch (SQLException e)
+        {
+            throw new SequenceManagerException(e);
+        }
+        finally
+        {
+            rsStmt.close();
+        }
+        return newid;
     }
 
     public void setReferenceFKs(Object obj, ClassDescriptor cld) throws SequenceManagerException

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to