Re: Internal Data Type for BOOL
Re: Internal Data Type for BOOL
- Subject: Re: Internal Data Type for BOOL
- From: Jonathan Rochkind <email@hidden>
- Date: Tue, 03 Jun 2003 12:50:40 -0500
At 11:11 AM 6/3/2003 -0600, Alex Eagar wrote:
I'm designing a new database for a WebObjects application. In EOModeler I
have an attribute called "gender" with an External Type as "BOOL" (using
MySQL). What is the best Internal Data Type or in other words, what's the
best Value Class to use? Can I simply use a Java "boolean"?
Ooh boy. My least favorite topic.
The overall problem here is that EOF was originally written in ObjC, where
basically a boolean type didn't exist, boolean was just a numeric type.
[Sort of. I'm sure I'm not describing the ObjC situation quite
accurately]. So this is good to keep in mind in wondering, "Why does it
work so screwy?".
But, you'll notice in EOModeler, that for "Internal Data Type",
boolean/Boolean isn't an option, even though you'd like it to be. Actually,
'boolean' couldn't really be an option unless the column can't be null in
the db---depending on the db and how you have it set up, this may or may
not be true. But Boolean then. But it's not an option.
So that leaves you with two choices. You could try using 'Custom' as the
'Internal Data Type', and then setting things up to convert to Boolean for
you. I've never tried that, but, at least in past versions of WO, it's
been reported to be a pain to get working. Or you could select 'Integer' as
the 'Internal Data Type'.
Which you'd think would mean it would end up as an Integer 0 or 1 in your
actual Java code. Which it can, if you want, but wait, there's more. If
you look at the Java code generated for an EnterpriseObject (aka 'EO', that
is an object from the db), you'll see that it uses storedValueForKey to get
the actual value for an attribute. As of WO 5.2, storedValueForKey does
something really tricky involving possible boolean attributes. If you have
an accessor method which returns 'boolean' or 'Boolean', storedValueForKey
will automatically convert the Integer to a Boolean for you. Which means
any of these things will theoretically work, with an attribute that is
boolean-valued in the db, with an Integer internal data type.
public Integer booleanAttribute() {
return (Integer) storedValueForKey("booleanAttribute");
//will return 0, 1, or possibly null
}
public Booelan booleanAttribute() {
return (Boolean) storedValueForKey("booleanAttribute");
// the storedValueForKey implementation uses reflection to see
//that you have a method named 'booleanAttribute' that returns
Boolean,
//so it converts to Boolean for you!
//will return Boolean equivelent to true, false, or possibly null.
}
public boolean booleanAttribute() {
Boolean b = (Boolean) storedValueForKey("booleanAttribute");
if ( b == null ) b = new Boolean(false);
return b;
//storedValueForKey will convert for you with a 'boolean' return
type too.
//returns boolean true or false.
}
And similarly, so long as a boolean/Boolean accessor method exists, you can
implement set methods simply like, for example:
public void setBooleanAttribute(boolean b) {
takeStoredValueForKey(new Boolean(b), "booleanAttribute");
}
So, this might sound really convenient, but hopefully you're still reading
because... I have noticed that the implementation here is very buggy. In
some very complicated and hard to figure out ways. Basically, the existence
of this 'automatic boolean conversion' feature seems to trigger some other
set of bugs with snapshots and saving. When you have attributes that are
being converted like this, sometimes saveChanges() doens't work properly,
doesn't actually save everything that should be saved. In a really hard to
predict way. Don't ask how long it took me to figure out that my weird
problems would go away if I simply avoided the automatic boolean conversion.
But anyway, I reccomend taking steps to _avoid_ the automatic boolean
conversion. It causes horrible problems. So what am I doing now? I make my
accessor method have a _different_ name than the a actual attribute, so
storedValueForKey won't figure out to convert it for me. And then I convert
it myself. For instance, the actual attribute, with an external boolean
type, internal type Integer, might be called 'booleanAttributeProtected'.
Now my method is:
public boolean booleanAttribute() {
Integer i = (Integer) storedValueForKey("booleanAttributeProtected");
//my own method to convert an Integer (or null!) to boolean true
or false
return convertToBoolean(i);
}
public void setBooleanAttribute(boolean b) {
takeStoredValueForKey( convertToInteger( b ),
"booleanAttributeProtected");
}
Hopefully you followed all that. That's what I'm doing now, anyway. Seems
to work. Kind of a pain, have to go in and mess with the
EOModeler-generated java code like that.
To make matters even worse, there seems to be some indication that
depending on the database and JDBC driver you are using, this stuff may
work slightly differently. But I think the method I suggest should be good
no matter what. I think.
Good luck.
--Jonathan
_______________________________________________
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.
_______________________________________________
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.