Re: WEIRD bug thing; 'shared' as reserved word? can you explain it?
Re: WEIRD bug thing; 'shared' as reserved word? can you explain it?
- Subject: Re: WEIRD bug thing; 'shared' as reserved word? can you explain it?
- From: Gary Teter <email@hidden>
- Date: Thu, 6 Feb 2003 13:38:40 -0800
We recently went through something similar to this while adding support
for database-agnostic boolean support in WireHose. I don't think it's
the name of the attribute that's causing the problem (though your
experiments seem to indicate otherwise; that might be due to fun with
classes that live in the default package that extend classes defined in
a package, or maybe that's a whole 'nother can of worms).
I believe the problem as you surmise is that takeStoredValueForKey ends
up calling your setShared method. Not sure why, but if you toss in a
bunch of new RuntimeException().printStackTrace() statements in there
you'll see it happening when you wouldn't expect. Drove me nuts for a
couple days trying to figure out why, then finally punted, figuring
Apple's keyvalue coding support classes will do as they please, and
it's just my job to work around unexpected behavior. :-)
What we ended up doing is having two sets of methods:
public boolean isShared() {
return booleanforKey("shared");
}
public void setIsShared(boolean value) {
takeBooleanforKey(value, "shared");
}
public Object shared() {
return storedValueForKey("shared");
}
public void setShared(Object value) {
takeStoredValueForKey(value, "shared");
}
(Implementation of "takeBooleanforKey" and "booleanforKey" left as
exercises :-)
You still use the "shared" attribute in your qualifiers, but you use
isShared in your java code. To make generating qualifiers easier we
ended up writing a method called "booleanQualifierForKey" that would
return an appropriate key-value qualifier depending on the attribute
type of the current database (1 or 0 for Integer, "Y" or "N" for char,
true/false for Boolean, etc.)
On Thursday, February 6, 2003, at 01:20 PM, Jonathan Rochkind wrote:
Okay, I kind of have this figured out now, but it took me half a day
to track down. Can anyone explain why 'shared' is a name you should
avoid using for an attribute in your EOs? In my migration from 5.0 to
5.2, I discovered this. Even though it didn't cause a problem in 5.0,
it caused a weird problem I can't entirely explain in 5.2, but
changing the attribute name fixed it.
For those really interested, here's a description. If you can come up
with a coherent explanation of what's going on, you get my eternal
respect as a true WebObjects genius-guru-expert.
I have an attribute called 'shared'. I use it as a boolean switch,
although in the db it's a numeric type. In 5.0, this means EOF would
return it as an Integer, and I wrote my own method to convert it to a
small-b boolean, no problem:
public boolean shared() {
return numberToBoolean( storedValueForKey("shared" );
}
public void setShared(boolean newShared) {
takeStoredValueForKey( booleanToNumber( newShared ), "shared");
}
Everything worked fine, but (this is important in a second), there
COULD be null values in the db. No problem, my conversion method
converted them to false. There were no problems.
Now, I convert to 5.2. In 5.2, if you have an attribute named 'foo',
and a method named foo() returning a boolean, like I had for 'shared',
storedValueForKey will automatically translate the numeric data to a
capital-B Boolean. Of course, I'm using a small-b boolean, no big
deal, but now my methods can simply look like this:
public boolean shared() {
return ((Boolean) storedValueForKey("shared")).booleanValue();
}
public void setShared(boolean newShared) {
takeStoredValueForKey( new Boolean(newShared), "shared");
}
Okay, no problem, for values in the db 1 and 0 (which is most of
them), this actually works fine. BUT. For null values in the db....
upon fetching a row that has a null in the 'shared' column, I get an
key value coding exception, unable to assign null to key shared. Of
course I can't assign null with the setShared method, but why is it
even using the setShared method, it should just be using
takeStoredValueForKey to initialize the new EO, no? And the million
dollar question---if my attribute is called anything else but shared,
this works FINE. NULL is reasonably translated to a Boolean 'false',
there is no exception. It's only when the attribute is called 'shared'
that there is a problem.
So, after a day of messing with this, I know I need to change the name
of my attribute to something to something other than 'shared'. Good
enough, it's a pain to make sure I haven't missed any EOQualifiers
with 'shared' in them, but at least I know what must be done. But I am
still completely baffled as to why. What's so special about the word
'shared' that makes things fail in such a truly bizarre way----that
is, only fail in very unusual circumstances (null value in the db that
normally you wouldn't expect), and only when the attribute is named
'shared'. Anyone?
--Jonathan
_______________________________________________
WebObjects-dev mailing list
email@hidden
http://www.omnigroup.com/mailman/listinfo/webobjects-dev
--
Gary Teter, Big Dog
Bulldog Beach Interactive http://www.bulldogbeach.com
_______________________________________________
webobjects-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/webobjects-dev
Do not post admin requests to the list. They will be ignored.