>>> Chuck Hill <[email protected]> schrieb am Mittwoch, 6. Mai
2009 um 18:51
in Nachricht
<[email protected]>:

> On May 5, 2009, at 11:33 PM, Andri vonAllmen wrote:
> 
>> Hi Chuck,
>>
>> thanks again for your efforts.
>>
>> >> 1. The data are inserted into the temporary table from the users
>> >> session and editing context.
>> > I think that is  the start of your problem.  What exactly are you 

>> doing?
>>
>> Basically I'm developing a reporting tool for generating reports  
>> (PDF, CSV, Excel, etc.) based on data coming out of a database.
>>
>> A report is generated as follows:
>>
>> 1.
>> The user selects data. This happens on one of many search interfaces
 
>> provided by the application (it's a ERP System). The selected data 

>> are fetched and either displayed on the user interface with the  
>> possibility to generate a report, or a report configuration window 

>> is shown directly (this configuration window is shown in every case 

>> before generating a report).
>>
>> The data that are fetched, are not stored permanently in the  
>> database in every case. It may be the case, that these data  
>> previously have been inserted into a temporary table (e.g. by a  
>> stored procedure) and are available for the report generation only.
>>
>> 2.
>> On the report configuration page, the user may select some  
>> predefined attributes and relationships available for the report,  
>> create report templates and so on. The available attributes and  
>> relationships are arranged by an admin, who has the possibility to 

>> travel along the whole object graph available based on a root
entity.
> 
> If you have just fetched the data from a temp table, how is it able
to  
> navigate the graph?
> 

I don't understand. I'm fetching some data from a temporary table.
These data may be attribute values as well as relationships. If it is a
relationship, i can follow the object graph to whatever comes behind, if
it is an attribute i can get its value.

> 
>>  3.
>> For generating a report, a thread is created and the already fetched
 
>> data as well as other report options are passed to this thread  
>> (happens in the constructor).
>>
>> 4.
>> The thread migrates the received data into its own editing context 

>> by faulting for the objects global id.
>>
>> 5.
>> The thread begins to handle all objects by processing the object  
>> graph using reflection.
>>
>> ---
>>
>> An Example not working for data whose source is a temporary table  
>> (reduced to the basics):
>>
>> # SEARCH ACTION (returning a report configuration window)
>> #
>> public WOComponent searchAction() {
>>     NSMutableDictionary storedProcDict = new NSMutableDictionary();
>>     storedProcDict.setObjectForKey(someValue, "someKey");
>>     ...
>>     // fill the temporary table
>>     EOUtilities.executeStoredProcedureNamed(editingContext,  
>> "fillTempTable", storedProcDict);
> 
> Why not pass this knowledge into the reporting thread so that it can 

> do the fetch and skip the migration?
> 

Because I can't assume, that a user does generate a report based on
data he is viewing (and that already have been fetched). And why should
the application fetch data inside some reporting module if a user is
just searching fore some data in some other module (and the user doesn't
want to generate a report at all).

> 
>>
>>     ...
>>
>>     // fetch data from temporary table
>>     EOFetchSpecification fetchSpecification = new  
>> EOFetchSpecification("tempTable", null, null);
>>     NSArray results =  
>> editingContext.objectsWithFetchSpecification(fetchSpecification);
> 
> 
>>
>>     // create and return the report configuration page (pop-up)
>>     ReportConfigurationPage page =  
>> (ReportConfigurationPage)pageWithName("ReportConfigurationPage");
>>     page.setRootEntity("TempTableObject");
>>     page.setModuleDescription("Some Module Name");
>>     page.setReportName("SomeReportName");
>>     page.setArrayWithFetchedObjects(results); // the results are  
>> migrated into the threads editing context in the threads
constructor
>>     page.setMigrateFromTempTable(true);
>>     return (WOComponent)page;
>> }
>>
>> # On the report configuration window, the user selects the  
>> attributes that shall be displayed on the report and finally starts 

>> the report generation (creates a thread)
>>
>> # THREAD CONSTRUCTOR
>> #
>>   public ReportThread(NSArray arrayWithFetchedObjects, Report  
>> report, String reportName, ReportTemplate selectedTemplate,  
>> NSDictionary titleDict, boolean migrateFromTempTable) {
>>   ...
>>   this.arrayWithFetchedObjects =  
>> XTEditingContext.migrate(arrayWithFetchedObjects); // right here the
 
>> migration is done which fails (only null values after migration)  
>> when passing data with a temporary table as source
>>   ...
>>   }
>>
>> # MIGRATION
>> #
>>   /** Moves database objects in an array into another editing  
>> context */
>>   public final static NSArray migrate(NSArray anArray,  
>> EOEditingContext newEditingContext)
>>   {
> 
> 
> What is the fetch lag on newEditingContext?  Is it rejecting the data
 
> from the temp table as the snapshots are too old?
> 

It depends. Some temporary tables keep the data for a single
transaction only, others as long as the database session is alive (ON
COMMIT PRESERVE ROWS / ON COMMIT DELETE ROWS for Oracle databases). I
have to deal with all possibilities.

Andri

> 
>>
>>     NSMutableArray returnArray = new NSMutableArray();
>>     Enumeration enumerator = anArray.objectEnumerator();
>>     while (enumerator.hasMoreElements()) {
>>       EOEnterpriseObject anEOEnterpriseObject =  
>> (EOEnterpriseObject)enumerator.nextElement();
>>       returnArray.addObject(migrate(anEOEnterpriseObject,  
>> newEditingContext));
>>     }
>>     return returnArray.immutableClone();
>>   }
>>
>>   /** Moves database object into another editing context */
>>   public final static EOEnterpriseObject migrate(EOEnterpriseObject 

>> enterpriseObject, EOEditingContext newEditingContext)
>>   {
>>     EOEnterpriseObject result = enterpriseObject;
>>
>>     // is there an object?
>>     if(enterpriseObject != null)
>>       {
>>       // old editing context
>>       EOEditingContext oldEditingContext =  
>> enterpriseObject.editingContext();
>>
>>       // only if object is in editing context and object is already 

>> not in
>>       // the new editing Context
>>       if(oldEditingContext != null && oldEditingContext !=  
>> newEditingContext)
>>         {
>>         // get global ID of the object
>>         EOGlobalID globalID =  
>> oldEditingContext.globalIDForObject(enterpriseObject);
>>
>>         // if the object has a global id
>>         if(globalID != null)
>>           // object with global id return to the editing context
>>           result = newEditingContext.faultForGlobalID(globalID,  
>> newEditingContext);
>>         }
>>       }
>>     return result;
>>   }
>>
>> ---
>>
>> Andri
>>
>> >>> Chuck Hill <[email protected]> Dienstag, 5. Mai 2009  
>> 17:12 >>>
>>
>> On May 5, 2009, at 5:30 AM, Andri vonAllmen wrote:
>>
>> > > There is something going on that you are not telling us.
>> >
>> > I'm also assuming, that my "problem" is something for the school
of
>> > bleeding obvious...
>> >
>> > However, by way of trial, I changed the temporary table to a
>> > permanent one, and my problems have been solved (temporarily).
Since
>> > I have to deal with temporary tables anyway, this did not help of
>> > course.
>> >
>> > The only "solution" that is working (as far as I can evakzate) is
>> > the following one:
>> >
>> > 1. The data are inserted into the temporary table from the users
>> > session and editing context.
>>
>> I think that is  the start of your problem.  What exactly are you  
>> doing?
>>
>>
>> > 2. For each record fetched, a new one is created in the memory
only
>> > (still in the user session and the object is not inserted into
any
>> > editing context at this point)
>>
>> "not inserted into any editing context"
>> EOF is not going to to like this.  Later, it will take revenge.
>>
>>
>> > 3. The memory objects are passed to the thread
>> > 4. The thread (assuming he has to deal with enterprise objects
only)
>> > has to insert these memory objects in its own editing context.
>>
>> EOF will not be too happy about this either.
>>
>>
>> > 5. If done as described above, from now on, all attributes and
>> > relationships are accessible.
>> >
>> > Note: point 2 does not work if using reflection (this, again,
does
>> > induce everything to return null values), I really had to do the
>> > following in the users session:
>> >
>> > NSMutableArray memoryObjects = new NSMutableArray();
>> > Enumeration enumerator = userSessionObjects.objectEnumerator();
>> > while (enumerator.hasMoreElements()) {
>> >  SomeEnterpriseObject aUserSessionObject =
>> > (SomeEnterpriseObject)enumerator.nextElement();
>> >  SomeEnterpriseObject aMemoryObject = new SomeEnterpriseObject();
//
>> > do not insert this one into any editing context (this is done by
the
>> > thread)
>> >  aMemoryObject.setName(anObject.name()); // using the getter and
>> > setter methods (this may be cumbersome for lots of attributes and
>> > relationships)
>> >  aMemoryObject.setXY(anObject.XY()); // using the getter and
setter
>> > methods (this may be cumbersome for lots of attributes and
>> > relationships)
>> >  ...
>> >
>> > That isn't nice, since every object is stored twice (for a short
>> > time only indeed) in the database, but it works.
>>
>> If you don't save, how is it in the database?
>>
>>
>> Chuck
>>
>>
>> >
>> > Andri
>> >
>> > >>> Chuck Hill <[email protected]> Freitag, 1. Mai 2009
16:50
>> > >>>
>> >
>> > On May 1, 2009, at 5:07 AM, Andri vonAllmen wrote:
>> >
>> > > Hi Chuck,
>> > >
>> > > thanks for your response.
>> > >
>> > > I can't fetch inside the thread because the thread did not
insert
>> > > the data into the temporary table
>> >
>> > Change it so that it does.  Move the code.
>> >
>> >
>> > > and can't access them at all. But the session should be able to
>> > > transfer these data to the thread somehow.
>> >
>> > Try fetching this temp data as raw rows instead of EOs.  Or do
you
>> > need the Java classes.
>> >
>> >
>> > >  I also tried to invoke all getter methods of the objects in
the
>> > > session for getting the attribute (and relationship) values in 

>> order
>> > > to set them to a newly created object (using reflection) by
using
>> > > the respective setter methods, but, with the same
results....the
>> > > getter methods already return null values (but they don't if
I'm
>> > > doing the same with some data from a "permanent" table).
>> > >
>> > > Using the mentioned copy code from Practical WebObjects didn't 

>> help
>> > > too.
>> > >
>> > > I can't figure out whats going wrong. Hard copying, refetching,
>> > > refreshing, faulting, everything i do, lets the objects forget 

>> about
>> > > their attributes values...
>> >
>> > There is something going on that you are not telling us.
>> >
>> >
>> > Chuck
>> >
>> >
>> > > >>> Chuck Hill <[email protected]> Mittwoch, 29. April
2009
>> > > 19:09 >>>
>> > > Hi Andri,
>> > >
>> > >
>> > > On Apr 29, 2009, at 5:19 AM, Andri vonAllmen wrote:
>> > >
>> > > > 'loha folks,
>> > > >
>> > > > short: How do i migrate data, fetched from a temporary table, 

>> from
>> > > > one editing context into another?
>> > > >
>> > > > Details below...
>> > > >
>> > > > The situation is as follows:
>> > > >
>> > > > First, data are inserted into a temporary table (Oracle 8i)
by
>> > using
>> > > > a stored procedure. Then, in the same procedure, these data
are
>> > > > fetched from the temporary table into the user sessions
editing
>> > > > context.
>> > > >
>> > > > Up to now, I've used ReportMill for generating reports based
on
>> > this
>> > > > temporary data. This happens in the same editing context and 

>> does
>> > > > not cause any problems.
>> > > >
>> > > > But since ReportMill isn't fun to work with at all, I've
decided
>> > to
>> > > > implement my own web-based reporting tool. This one generates 

>> the
>> > > > report in its own thread and uses its own editing context (no
>> > shared
>> > > > editing context). It works by simply processing a object graph
 
>> and
>> > > > invoking all methods (attributes, relationships) using  
>> reflection
>> > > > (java.lang.reflect) based on some root objects that have to
be
>> > > > passed to the reporting tool.
>> > > >
>> > > > Since the data source is a temporary table in this case, the 

>> data
>> > > > objects can't be inserted into another editing context,  
>> because an
>> > > > exception, telling that these objects can't be registered in
two
>> > > > editing contexts, would be (and is) shown.
>> > >
>> > > It sounds to me like you were doing something wrong.  Why not
just
>> > > fetch the data into the thread's EC instead of the session's?
>> > >
>> > >
>> > > >  So, I've tried to migrate them into a new editing context by
>> > > > faulting for the objects global id in the original editing
>> > context.
>> > > > This basically works, but the migrated data, namely all  
>> attribute
>> > > > values, relationships etc. are NULL.
>> > >
>> > > I don't understand why that should be.
>> > >
>> > >
>> > > > For permanent tables, this way of migration works well (code
>> > below):
>> > > >
>> > > > EOEditingContext oldEditingContext =
>> > > > enterpriseObject.editingContext();
>> > > > EOGlobalID globalID =
>> > > > oldEditingContext.globalIDForObject(enterpriseObject);
>> > > > result = newEditingContext.faultForGlobalID(globalID,
>> > > > newEditingContext);
>> > > >
>> > > > Another trial was, to "copy" all objects, telling the old  
>> editing
>> > > > context to forget about them and inserting the copy into the
new
>> > > > editing context (see code below).
>> > > >
>> > > > EOEnterpriseObject result = enterpriseObject;
>> > > >  
>> enterpriseObject.editingContext().forgetObject(enterpriseObject);
>> > > > newEditingContext.insertObject(result);
>> > > >
>> > > > But this does not work either. When trying to get some  
>> attributes
>> > > > value or another object reachable over a relationship, still
>> > null is
>> > > > returned.
>> > >
>> > > Because you told it to forget the data!
>> > >
>> > >
>> > > > BUT, when adding e.g. a system out BEFORE migrating the data,
>> > > > accessing some value (e.g. the primary key), the migrated data
 
>> are
>> > > > not null (in fact, now all attributes and relationships and so
 
>> on
>> > > > are accessible and do return the correct value).
>> > >
>> > > That is because it then faults in the data.
>> > >
>> > >
>> > > >  Since I'm treating this phenomenon for hours and don't see
the
>> > > > light, I finally have to ask for help. Any hints would be
>> > > appreciated.
>> > >
>> > > I'd try and fetch directly into the thread's EC.  Failing that,
>> > > Practical WebObjects has code to copy a graph of objects.
>> > >
>> > >
>> > > Chuck
>> > >
>> > >
>> > > --
>> > > Chuck Hill             Senior Consultant / VP Development
>> > >
>> > > Come to WOWODC'09 in San Fran this June!
>> > > http://www.wocommunity.org/wowodc09/
>> > >
>> > > _______________________________________________
>> > > 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/ava
>> > %40cedes.com
>> > >
>> > > This email sent to [email protected]
>> >
>> > --
>> > Chuck Hill             Senior Consultant / VP Development
>> >
>> > Come to WOWODC'09 in San Fran this June!
>> > http://www.wocommunity.org/wowodc09/
>> >
>> > _______________________________________________
>> > 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/ava
>> %40cedes.com
>> >
>> > This email sent to [email protected]
>>
>> -- 
>> Chuck Hill             Senior Consultant / VP Development
>>
>> Come to WOWODC'09 in San Fran this June!
>> http://www.wocommunity.org/wowodc09/
>
 _______________________________________________
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