cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robert Zeigler <robert.zeig...@gmail.com>
Subject Re: Cayenne 101
Date Fri, 26 Dec 2008 22:01:58 GMT
Shouldn't have to do that, but it depends, in part, on how things are  
modeled.
Cayenne can manage the relationship object graph for you.

In older versions of cayenne, you had to explicitly register E1 before  
associating it with E2.  In current versions of cayenne, as long as / 
one/ of the entities is registered with an object context, you can  
associate the two entities, and if the other is not registered, it  
will be auto-registered (note: if both objects are registered, but  
they are registered to different object contexts, you'll get an  
exception).

So, for Question 1:
	E2 e2 = new E2();
	e1.addToE2List(e2);
	or

	E2 e2 = new E2();
	e2.setE1(e1);

	or
	
	//following is 3.0M5-based code
	ObjectContext oc = BaseContext.getThreadObjectContext();
	E2 e2 = oc.newObject(E2.class);
	e2.setE1(e1);
	
	or
	ObjectContext oc = BaseContext.getThreadObjectContext();
	E2 e2 = oc.newObject(E2.class);
	e1.addToE2List(e2);

Any of those will work just fine and be equivalent.

For Question 2:
	At least in 3.0, as long as your relationships are properly mapped,  
simply doing:
	ObjectContext oc = BaseContext.getThreadObjectContext();
	oc.deleteObject(e2);
	oc.commitChanges();

Will work, and the object should be removed from all associated  
relationships.
	
For example, using 3.0M5, I just wrote the following test (which  
passes) in a project of mine to illustrate the behavior.
Note that "createRole" is a convenience method which creates a  
UserRole, registers it with the thread-bound ObjectContext, sets  
default properties, and commits the object to the database.
UserRole has a one-to-many relationship with Parent.  Conversely,  
Parent has a ManyToOne relationship with UserRole.

	public void testRelationshipDeleting() {
		ObjectContext oc = BaseContext.getThreadObjectContext();
		UserRole role = createRole("test role");
		
		Parent p = new Parent();
		p.setUsername("somelogin");//username and password are required.
		p.setPassword("somepassword");
		p.setUserRole(role);
		
		assertTrue(role.getParentsInRole().contains(p)); //note that even  
before the commit, cayenne has updated the object graph so the parent  
is in the list.
		
		oc.commitChanges();
		
		assertTrue(role.getParentsInRole().contains(p));
		
		oc.deleteObject(p);
		assertFalse(role.getParentsInRole().contains(p));//note that even  
before committing changes, the parent has been removed from the  
relationship.
		
		oc.commitChanges();
		assertFalse(role.getParentsInRole().contains(p));
	}



One line of code you have below has me raising my eyebrows a bit, and  
that's the dc.commitChangesToParent().  That's only used/needed for  
nested data contexts.  Based on the rest of your code, it doesn't look  
like you're using nested data contexts.  See: http://cayenne.apache.org/doc/nested-datacontexts.html

  for more information.
Suffice it to say that you probably don't need  
dc.commitChangesToParent();

Robert

On Dec 26, 2008, at 12/261:05 PM , Joe Baldwin wrote:

> This accounts for the totally weird results.  Ref to "what [I]  
> want".  As usual with software, I would like to make a change in one  
> place vs two or three places.  I guess I am still thinking of this  
> from a RDB point of view.  It sounds like you are telling me, that I  
> must update all of the relationships via explicit code references  
> and then commitChanges.
>
> Is this correct?
>
>
>
> On Dec 26, 2008, at 2:19 PM, Pierre Lavignotte wrote:
>
>> Hi Joe,
>>
>> Question 1 :
>>
>> you can't call the object constructor. Use the DataContext method  
>> instead
>> because it will register the object too.
>>
>> Question  2 :
>> It depends what you want !
>>
>> DataContext dc = DataContext.
>>
>> getThreadDataContext();
>>> E1.getE2List().remove(e2);
>>> dc.commitChanges();
>>
>> This will remove the link between E1 and E2 but E2 will still exist.
>>
>> DataContext dc = DataContext.
>>
>> getThreadDataContext();
>>> dc.deleteObject(e2);
>>> dc.commitChangesToParent();
>>> dc.commitChanges();
>>
>>
>> This will delete E2... but I think it will still be present in
>> E1.getE2List() because the list can be in memory.
>> I know it's not logical but I'm quite sure I allready encontered  
>> this case.
>>
>> I use Cayenne 2.0.4 so Cayenne 3.0 can differ in some points.
>>
>> Pierre
>>
>>
>> Cordialement,
>> Pierre Lavignotte
>> Ingénieur Conception & Développement
>> http://pierre.lavignotte.googlepages.com
>>
>>
>> On Fri, Dec 26, 2008 at 6:32 PM, Joe Baldwin  
>> <jfbaldwin@earthlink.net>wrote:
>>
>>> I have a few questions about best practices.   I have done some
>>> experimenting, have read what I could find, and have some  
>>> questions about
>>> some elementary Cayenne usage concerning Add & Delete with a
>>> Parent-ChildList design.  (I have recently experienced some odd  
>>> behavior
>>> that may be due to a fundamental misunderstanding of DataContext  
>>> rules.)
>>>
>>> Environment: I am using 3.0 M4 with MySQL and Tomcat JSP
>>> DataContext:  I am getting the context using:
>>> DataContext.getThreadDataContext();
>>> Example Design:
>>>      E1 has a list of E2's
>>> that is:
>>>      E2 is a child of E1 and is a many-to-one relationship.
>>>      The E1 relationship is called "E2List" and the reverse  
>>> relationship
>>> on E2 is called "E1".
>>>
>>> Questions:
>>> 1. When creating and associating E2 children is it more proper to  
>>> do the
>>> following:
>>>
>>>      DataContext dc = DataContext.getThreadDataContext();
>>>      ** [get E1 via a  DataContext query]
>>>      E2 e2 = new E2();
>>>      e2.setE1(e1); // I **assume** this registers e2 with the  
>>> Context &
>>> adds e2 to e1's list
>>>      dc.commitChanges();
>>>
>>> OR do you need to do as your example suggests:
>>>
>>>      DataContext dc = DataContext.getThreadDataContext();
>>>      E2 e2 = (E2) dc.newObject(E2.class);
>>>      e2.setE1(e1);
>>>      dc.commitChanges();
>>>
>>> OR is there a better way?
>>>
>>> 2. Removal of a Child
>>> Can you remove the child using:
>>>      DataContext dc = DataContext.getThreadDataContext();
>>>      dc.deleteObject(e2);
>>>      dc.commitChangesToParent();
>>>      dc.commitChanges();
>>>
>>> or must you do it via the parent:
>>>      DataContext dc = DataContext.getThreadDataContext();
>>>      E1.getE2List().remove(e2);
>>>      dc.commitChanges();
>>>
>>> (Note: the second method seems to work better.)
>>>
>>> Thanks,
>>> Joe
>>>
>>>
>


Mime
View raw message