Hi Craig,
>I'll assume that where you wrote:
>newexpensesentry.ToExpensetype((...)
>
>you meant
>newexpensesentry.setToExpensetype((...)
>-----------------^^^
oups, sorry, yes you're right I meant the above
(newexpensesentry.setToExpensetype((...))
Oh thanks now I learned about "hollow" state
I get the properties by the generated accessor methods:
where newexpensesentry is the one after I inserted the values into the
db and then got this one by running a new query
String projectname = newexpensesentry.getToProjects().getName();
which returns me null:
String expenstype = newexpensesentry.getToExpensetype().getExpensetype();
which returns me the expensetype, this works, and I set the ExpenseType
exact the same way as the Project:
((Expensetypes)theDataContext.registeredObject(new
>> ObjectId(Expensetypes.class, "id",new Integer(1)))));
If I do this with a new DataContext (not the same as I used to save the
object) then everything works fine.
Now I found out that i have the same behaviour regardless of if I create
a new Expenses object and register it with the DataContext, fill set its
properties and save it, or if I edit an existing one and the get the
object back by a new SelectQuery, and again with a new DataContext it works
her is the code with which I take n Expenses from a struts ActionFormBean
the code does the following: it checks if it has to create a new
Expenses object or edit an existing and the fills the values from the
form, the caller of thes form then calls:
theDataContext.commitChanges(Level.WARN);
this works fine in the console window if my IDE (eclipse, this one's
cool :-))) I can see that objects are updated and inserted according the
data passed from the form
public static void populateExpenses(ExpensesDataForm expensesdataform,
DataContext theDataContext)
{
List expensesBOlist = expensesdataform.getExpensesBOsList();
int sizebefore = expensesBOlist.size();
for(int i = 0; i < expensesBOlist.size(); i++)
{
ExpensesBO theexpensesfromForm = (ExpensesBO)expensesBOlist.get(i);
Expenses origexpenses = null;
if(ApplicationConstants.NEWEXPENSES.equals(theexpensesfromForm.getID()))
{
if(!ApplicationConstants.NEWPROJECT.equals(new
Integer(theexpensesfromForm.getSelectedProject())))
{
origexpenses =
(Expenses)theDataContext.createAndRegisterNewObject("Expenses");
origexpenses.setInvoiced(new
BigDecimal(ApplicationConstants.ISNOTINVOICED));
}
}
else
{
origexpenses = theexpensesfromForm.getTheExpense();
}
if(origexpenses != null)
{
origexpenses.setAmount(getBigDecimalFromString(theexpensesfromForm.getAmount()));
origexpenses.setExpensedate(new java.sql.Date(
DateFormatter.stringToDate_DDMMYYYY(theexpensesfromForm.getExpenseDate()).getTime()));
origexpenses.setToEmployees(EmployeeService.findEmployeeByID(theDataContext,
new Integer(expensesdataform.getUserWhoWantsToRapport())));
origexpenses.setToExpensetype(ExpenseTypesService.findExpenseTypesByID(theDataContext,
new Integer(theexpensesfromForm.getSelectedExpenseType())));
origexpenses.setToProjects(ProjectsService.findProjectsByID(theDataContext,
new Integer(theexpensesfromForm.getSelectedProject())));
//theexpensesfromForm.getSelectedProject() returns me the correct
//projectID of an existing project in DB, checked this in debugger
origexpenses.setHours(getBigDecimalFromString(theexpensesfromForm.getHours()));
origexpenses.setInvoicable( new BigDecimal(
theexpensesfromForm.getInvoicable() ? ApplicationConstants.ISINVOICABLE
: ApplicationConstants.ISNOTINVOICABLE));
origexpenses.setNotice(theexpensesfromForm.getNotice());
origexpenses.setNumberofkm(getBigDecimalFromString(theexpensesfromForm.getNumberofkm()));
origexpenses.setToEmployeesResponsible(EmployeeService.findEmployeeByID(theDataContext,
new Integer(expensesdataform.getUserWhoWantsToRapport())));
//todo herausfinden, wer verantwortlich ist
//origexpenses.setResponsible()
}
}
}
the findXXXbyID look all the same, here one as an example:
public static Projects findProjectsByID(DataContext theDataContext,
Integer projectsID)
{
return (Projects)theDataContext.registeredObject(new
ObjectId(Projects.class, "ID",projectsID.intValue()));
}
here's the code whith which I get a list of Expenses (if I set the same
time range as for the above inserted Expenses, which I do for testing)
then I get the same objects as I inserted or updated above:
public static List getExpenses4EmployeeInTimeFrame(DataContext
theDataContext, Date beginDate, Date endDate, Employees theemployee)
{
Expression employeeidexpr = ExpressionFactory.binaryPathExp(
Expression.EQUAL_TO,
"ToEmployees",
theemployee);
Expression begindateexpr = ExpressionFactory. binaryPathExp(
Expression.GREATER_THAN_EQUAL_TO,
"expensedate",
beginDate);
Expression enddateexpr = ExpressionFactory.binaryPathExp(
Expression.LESS_THAN_EQUAL_TO,
"expensedate",
endDate);
employeeidexpr = employeeidexpr.andExp(begindateexpr).andExp(enddateexpr);
SelectQuery query = new SelectQuery("Expenses", employeeidexpr);
query.addOrdering("expensedate", true);
return theDataContext.performQuery(query);
This is the code which is running, thanks again for your time and have a
nice day, greetings from cold switzerland
martin
>(If not, then that would be *very* interesting and maybe indicative of >a
>problem).
>
>As to what the real problem may be:
>Assuming that you are setting the toProjects in the same way as below
>(obtaining it from theDataContext.registeredObject, by primary key),
>then the object returned will be "hollow". The object (Project) will
>not be fetched from the db until it's properties are read. So, the big
>question is how are you reading it's properties? If you are using
>readPropertyDirectly, then you are seeing expected behaviour....
>readPropertyDirectly will not automatically fetch a HOLLOW object. You
>have to use either readProperty (defined on CayenneDataObject rather
>than DataObject), or the standard accessor methods (getTitle() etc.)
>
>If you are using the standard accessor methods, as generated by >Cayenne,
>then something else strange is occuring. More code would help, if
>you're permitted to send it (e-mail me privately if public distribution
>is an issue).
>Hope this (or something else) helps,
>Craig Miskell
>On Fri, 2002-12-13 at 07:03, martin ruff wrote:
>> Hi I've got the following table
>> CREATE TABLE expenses(
>> id serial NOT NULL PRIMARY KEY,
>> fk_employeeid int4 NOT NULL,
>> fk_projectid int4 NOT NULL,
>> expensedate date NOT NULL,
>> fk_expensetype int4 NOT NULL,
>> notice varchar(2000) NOT NULL,
>> numberofkm numeric,
>> hours numeric,
>> amount numeric,
>> invoicable numeric(1),
>> invoiced numeric(1),
>> responsible int4 NOT NULL,
>> FOREIGN KEY (fk_employeeid) REFERENCES employees (id),
>> FOREIGN KEY (fk_projectid) REFERENCES projects (id),
>> FOREIGN KEY (fk_expensetype) REFERENCES expensetypes (id),
>> FOREIGN KEY (responsible) REFERENCES employees (id));
>>
>> What I do:
>> I create a new Expenses object and register it with DataContext:
>> Expenses newexpensesentry =
>> (Expenses)theDataContext.createAndRegisterNewObject("Expenses");
>> then I fill all the values into that object I've defined relations >for
>> the fk_.. references
>>
>> <obj-relationship name="ToEmployees" source="Expenses"
>> target="Employees" toMany="false">
>> <db-relationship-ref source="expenses" target="employees"
>> name="ToEmployees"/>
>> </obj-relationship>
>> <obj-relationship name="ToEmployeesResponsible" source="Expenses"
>> target="Employees" toMany="false">
>> <db-relationship-ref source="expenses" target="employees"
>> name="ToEmployeesResponsible"/>
>> </obj-relationship>
>> <obj-relationship name="ToExpensetype" source="Expenses"
>> target="Expensetypes" toMany="false">
>> <db-relationship-ref source="expenses" target="expensetypes"
>> name="ToExpensetype"/>
>> </obj-relationship>
>> <obj-relationship name="ToProjects" source="Expenses" >target="Projects"
>> toMany="false">
>> <db-relationship-ref source="expenses" target="projects"
>> name="ToProjects"/>
>> </obj-relationship>
>>
>> then I set the refenrenced objects i.e.
>>
>>newexpensesentry.ToExpensetype((Expensetypes)theDataContext.registeredObject(new
>> ObjectId(Expensetypes.class, "id",new Integer(1)))));
>> I have the find the referenced object via it's primary key because
>>from
>> a web-interface I only get the primary key for the referenced object
>>and
>> not the object itself
>> I do this for all the referenced objects:
>> then I call theDataContext.commitChanges(Level.WARN);
>> everything works fine, the problem comes now:
>> If I get a list of expenses in a timerange (the Expense object
>>inserted
>> above is under the returned objects), then the newly created Expense
>> objects I get in return from my query has an empty (properties are
>> empty) Projects (relation ToProjects) objects related to it. The
>>strange
>> thing is, that the ExpenseType object that I get over the relation
>> ToExpensetype is ok.
>> If I create a NEW DataContext and rerun the query, again, everything
>>is
>> ok, also the Projects object thas had empty properties before.
>> If I use THE SAME DataContext to insert a new Espense object and the
>>run
>> the query I get problems as described above.
>> Has anyone a idea what the problem could be here?
>> thanks in advance
>> martin
>>
This archive was generated by hypermail 2.0.0 : Thu Dec 12 2002 - 16:08:00 EST