Re: Obscure Primary Key Gotcha
Re: Obscure Primary Key Gotcha
- Subject: Re: Obscure Primary Key Gotcha
- From: Paul Lynch <email@hidden>
- Date: Sun, 22 Oct 2006 21:10:54 +0100
A couple of people wrote to suggest that I could use a database
context delegate to force acceptance of a float PK. Somewhat to my
surprise, it worked - I ran a test using Pierre's example code, more
or less. I was expecting EO to use the same check to see if returned
PKs are non-null/non-zero as it uses for the initial supplied PK, but
it obviously doesn't.
Regardless of this, as I have said elsewhere, I will still prefer to
change the database structure rather than continue with a float PK.
Paul
On 21 Oct 2006, at 23:13, Pierre Bernard wrote:
Hi!
My guess is that someone tested for zero value using number.intValue
() == 0. This of course does rounding first and only then compares
to 0. The correct way of doing things would have been to use a
compare() method. Guess that's worth a bug report.
I believe you can work around the bug by plugging in your own
primary key generation. It gets called whenever EOF deems the
existing values inadequate for being a primary key. So you would
first get the existing value. If it exists you return it to EOF.
Only if it doesn't you go on to generate a new one.
public NSDictionary databaseContextNewPrimaryKey(
EODatabaseContext dbContext,
Object o,
EOEntity entity)
{
NSDictionary pk = null;
if (o instanceof EOEnterpriseObject)
{
// Do not generate new primary keys for objects that already
have one
pk = primaryKeys((EOEnterpriseObject)o);
}
if (pk == null)
{
pk = primaryKeyDictionaryForDatabaseContextAndEntity(dbContext,
entity);
}
return pk;
}
public static NSDictionary
primaryKeyDictionaryForDatabaseContextAndEntity(
EODatabaseContext dbContext,
EOEntity entity)
{
NSDictionary pk = null;
try
{
dbContext.lock();
EOAdaptorChannel adaptorChannel =
dbContext.availableChannel().adaptorChannel();
if (!adaptorChannel.isOpen())
{
adaptorChannel.openChannel();
}
pk =
(NSDictionary)adaptorChannel
.primaryKeysForNewRowsWithEntity(1, entity)
.lastObject();
}
catch (Exception e)
{
NSLog.error.appendln(
"Can't get primary keys for entity "
+ entity.name()
+ " "
+ e);
}
finally
{
dbContext.unlock();
}
return pk;
}
Pierre
On 19 Oct 2006, at 21:09, Paul Lynch wrote:
I just came across this, and thought the list might be interested:
I was just working with a legacy database which has a table with a
single column, which is of course designated as the primary key.
It happens to be a float, represented as a BigDecimal. The
(somewhat dubious) logic behind this design isn't important.
If I add a record to the table (EOGenericRecord), with the key
field set to a number greater than 1.0, everything is fine.
However, if I add a record with a value between 0 and 1.0 (which
is the vast majority of the records required), WO silently
replaces the value with the next available value from EO_PK_TABLE.
The reason behind this is that EO expects a primary key, when
supplied by the user, to be non-null and non-zero. It is
obviously (and mistakenly) assuming that values less than 1 are
equal to zero - probably because some programmer in the past
thought that no one would be dumb enough to use a float as a
primary key :-).
Incidentally, the above is what happens using OpenBase; the MySQL
driver just generates an exception claiming it is unable to
generate a primary key.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden