On Jul 11, 2006, at 9:23 AM, Randy Wigginton wrote:


I am getting a very strange error when I use my own EODelegate. For management reasons I am required to use MySQL. The PK support for MySQL out of the box for EOF is not thread safe; I can get duplicate IDs. Thus, I've created a very simple delegate, which looks like this:

        public myEODelegate() {
                EODatabaseContext.setDefaultDelegate(this);
        }
        private  static NSArray keys = new NSArray("pk");
public NSDictionary databaseContextNewPrimaryKey(EODatabaseContext dbCtxt, Object object, EOEntity entity) {
                NSArray keyNames = entity.primaryKeyAttributeNames();
                if (keyNames.size()!=1)
                        return null;
                String pkName = (String)keyNames.get(0);
                try {
                        EOEditingContext ec = new EOEditingContext();
NSArray rawRows = EOUtilities.rawRowsForSQL(ec, "testit", "UPDATE EO_PK_TABLE SET pk=pk+1 where lower(name) ='"+entity.externalName().toLowerCase()+"'"); rawRows = EOUtilities.rawRowsForSQL(ec, "testit", "select pk from eo_pk_table where lower(name)='"+entity.externalName ().toLowerCase()+"'", keys);

That may be better than the default MySQL stuff, but you still have a race condition there. You need to do this in the context of a transaction.

                        NSDictionary foo = (NSDictionary)rawRows.get(0);
                        Long bd = (Long)foo.valueForKey("pk");

I suspect that this is your problem. Looking below, it seems that EOF is expecting an Integer.

                        return new NSDictionary(bd, pkName);                    
        
                } catch (Exception e) { // Use default delegate
                        return null;
                }
        }

The problem is this. I have a relationship, Owner and subguy. Owner has a primary key; subguy is owned by Owner. In the relationship, Owner propagates the primary key and owns the destination. Here is some code that will always fail:
                allDelegate = new myEODelegate(); // turn on my delegate

                EOEditingContext ec = new EOEditingContext();
                NSLog.allowDebugLoggingForGroups(0x10000L);
                Owner   own = 
(Owner)EOUtilities.createAndInsertInstance(ec,"owner");
                Subguy gag = aag.sub();
                gag.setGoogleID(new Integer(1001));
                ec.saveChanges();
                gag.setContentBid(new Double(1.01));
                ec.saveChanges();

What is VERY strange is that if I delete the first saveChanges(), everything works. With it there, I get an exception: <main> A fatal exception occurred: cannot update primary-key 'adGroupID' from '13' to '13' on object:{values = {googleID = 1001; contentBid = 1.01; adGroupID = 13; }; this = "<Subguy 8a3fe6 _EOIntegralKeyGlobalID[subguy (java.lang.Integer)13]>"; } of entity: subguy in databaseContext [EMAIL PROTECTED]

Notice that this says _EOIntegralKeyGlobalID[subguy (java.lang.Integer)13] while your delegate returns a Long. The real message should probably be cannot update primary-key 'adGroupID' from '(java.lang.Integer)13]' to '(java.lang.Long)13]'.

Do the PK columns in the model have a Value Type of l (that is an L)? What happens if you convert the Long to an Integer in your delegate method?


Chuck


--
Coming sometime... - an introduction to web applications using WebObjects and Xcode http://www.global-village.net/wointro

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems. http://www.global-village.net/products/practical_webobjects




_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to