Hi Fabian,
Fabian Peters wrote:
I stumbled across a known bug in the loading of shared EOs when an
App uses multiple models. I got it working now, so this post is
more to add some info for future reference and maybe have some WO-
guru look into it. ;-)
[1] <http://en.wikibooks.org/wiki/Programming:WebObjects/EOF/
Using_EOF/Problems>
[2] <http://wonder.cvs.sourceforge.net/wonder/Wonder/Common/
Frameworks/ERExtensions/Sources/er/extensions/
ERXSharedEOLoader.java?revision=1.9&view=markup>
Unlike the case of Francis Labrie [1], changing the model load
order did not help in my case. However, the ERXSharedEOLoader [2],
originally written by Kelly Hawks, did. Kelly's description of the
situation, as quoted in the class, does not match mine. I actually
have EOs that are shared in each of two models. With this setup, I
get:
INFO 11:04:55 14,99 MB used/6,81 MB free
er.transaction.adaptor.Exceptions:85 - JDBC Exception occured:
java.lang.IllegalStateException: sqlStringForKeyValueQualifier:
attempt to generate SQL for
com.webobjects.eocontrol.EOKeyValueQualifier (myAttribute =
'myValue') failed because attribute identified by key
'myAttribute' was not reachable from from entity 'sharedEO1'
This is the same problem Francis ran into.
Well, I think while the exception you get looks similar, your problem
seems to be different. See below.
In my case I've got a Foo object in Model A, which has a relation
to a Bar object in Model B. Bar has a relation to Baz (Model B) and
Baz has relations to two shared EOs, sharedEO1 and sharedEO2 (both
Model B). This triggers the exception:
NSArray arr = EOUtilities.objectsMatchingKeyAndValue
(ec, Foo.ENTITY_NAME,
Foo.ATTRIBUTE_myAttribute, sess().getFoo
().myAttribute());
Instead of just fetching Foo records matching the given attribute,
the code results in a fetch for each of the shared EOs. This is I
can understand, but then, a fetch is prepared for the Foo entity,
which looks like this when logged at
PostgresqlExpression.prepareSelectExpressionWithAttributes():
PostgresqlExpression.prepareSelectExpressionWithAttributes:
NSArray: (<EOAttribute someAttributeOfSharedEO2 2757372>,
<EOAttribute eoid 4488117>, <EOAttribute message 1435205>,
<EOAttribute private 12647729>, <EOAttribute
anotherAttributeOfSharedEO2 3070175>, <EOAttribute temporary
10507805>)
FetchSpec: <class com.webobjects.eocontrol.EOFetchSpecification
(entityName=Foo,
qualifier=((myAttribute = 'myValue')),
isDeep=true, usesDistinct=false,
sortOrdering=null,
hints=null,
_prefetchingRelationshipKeyPaths = null)>
This is very interesting: it seems your Foo fetch is done while some
references to old result sets of old entities are still there in the
EOAccess layer...
It looks like an initialization issue in EOF: _propertiesToFetch()
method in EODatabaseChannel class seems to return a bad attributes
array in the _selectWithFetchSpecificationEditingContext
(EOFetchSpecification, EOEditingContext) which is called by the
selectObjectsWithFetchSpecification(EOFetchSpecification,
EOEditingContext) method. I think maybe one of the following scenario
may match your case:
1. The protected _resultSet ResultSet instance attribute in the
JDBCChannel class has not been initialized before the Foo fetch, so
it still hold a reference to the last EOShared attributes previously
fetched. This _resultset is normally set in the _evaluateExpression
(EOSQLExpression, boolean, boolean) method and cleared in the
_endFetch() method.
2. The _currentEntity in the EODatabaseChannel has not been
initialized before the Foo fetch, so it still hold a reference to the
last fetched EOShared.
I don't really know what is happening here, but what I see is that
the attributes listed, all belong to sharedEO2, while the
entityName is correctly set to "Foo". So, somehow the attributes of
the last fetch for all instances of sharedEO2 end up in the fetch
for Foo and the fetch is recognised to be for entity sharedEO2 -
albeit the correctly set entityName.
On subsequent invocations, the attributes all belong to "Foo" and
the fetch completes normally.
Yes, I think it may be related to the shared entities fetch only.
I've had enough for today and won't look into this any further.
Maybe somebody gets some clues from my notes...
I think you could avoid this problem with a simple automatic model
initialization on application startup. You just have to register a
method to the WOApplication.
ApplicationDidFinishLaunchingNotification notification. In this
method, you loop through each model of your model group and perform
an assertConnectionDictionaryIsValid() to each adaptor associated to
the model database context. This will open the connections to the
databases and all shared entities will be fetch a this time, and not
just before your Foo fetch.
Kind regards,
--
Francis Labrie
Saint-Bruno-de-Montarville, Quebec, Canada
_______________________________________________
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]