I've got a group entity with this property:
property name="members" fieldType="many-to-many"
cfc="root.model.user.user" linktable="group_member"
fkcolumn="groupidfk" inversejoincolumn="useridfk" lazy="true"
singularname="member";
When I run addMember to a group, I've noticed that the SQL actually
deletes all records in the link table that belong to the group and
than re-adds every single member.
--
===========================================================================
Raymond Camden, ColdFusion Jedi Master
Email : r...@camdenfamily.com
Blog : www.coldfusionjedi.com
AOL IM : cfjedimaster
Keep up to date with Android news: http://www.androidgator.com
property name="groups" fieldType="many-to-many"
cfc="root.model.group.group" linktable="group_member"
fkcolumn="useridfk" inversejoincolumn="groupidfk" lazy="true";
No inverse=true.
Sent from my iPhone
Should I switch to using vanilla SQL then?
--
Bob Silverberg
www.silverwareconsulting.com
My logic would be that the values would only get changed if one was to
change the primary key, surely it would be far better to do an update than
do a delete, and rebuild it.
Is this a hibernate problem or a ColdFusion problem?
Cheers,
Sam
Sent from my iPhone
If you have a bi-directional relationship you should always set *both*
sides of the relationship whenever you want to persist it. In the
example of User and Group that means you should call user.addGroup()
and group.addUser(). This keeps your model in a consistent state.
Much as it seems counter-intuitive (to me anyway), Hibernate does not
do that for you automatically, and you can run into problems if you
don't follow that rule. One upside of following that rule is that
you'll never have issues with a relationship not getting persisted
when inverse is set to true on one side (which is another important,
and often missed rule).
There have been a number of blog posts written about this. I wrote a
few and I believe that Brian and Barney have written some as well.
I don't believe that any of this will address the issue of the 800
inserts, though. This is just additional information.
Bob
--
Bob Silverberg
www.silverwareconsulting.com
Are you saying if I had done user.addGroup() it would have done a
single insert? Even if not, users will never have that many groups so
it should perform a lot better.
In my case, groups can add members and users can add groups, so
"natural" is certainly up to debate. ;)
> It is "always" (for me) on the <one-to-many> side, where I set the inverse
> attribute.
That makes sense - but this is m2m.
> I hoped I have helped some - and if not - then perhaps you can just take it
> as "gospel" for now - until such time as it does click for you?
Yeah, I'm going to try.
In group.cfc I added inverse=true to the property.
In my groupService I now do:
group.addMember(user);
user.addGroup(group);
In the MySQL log I see much better SQL being used.
As a side question, groups also have Admins and Moderators, which are
also m2m, but since users don't join them per se, I've only defined it
on one side. There is no user.adminGroups or user.moderatorGroups.. Is
that an issue I should correct? I never ask a user for the groups he
admins. But I did end up adding a getGroups method like so: (notice
there is also a 4th way to be associated with a group - being it's
owner)
public array function getGroups() {
var hql = "from group g where exists(from g.members m where m.id =
:myid) or exists(from g.moderators m2 where m2.id = :myid) or
exists(from g.admins m3 where m3.id = :myid) or (g.owner.id = :myid)
order by name asc";
var res = ormExecuteQuery(hql, {myid=variables.id});
return res;
}
--
I find this all really interesting, having to call and establish the relationship on both sides like that seems so counter intuitive, twice as much code and you would imagine you would need.
Which of these do you then have to pass to the save()? Both of them? Either?
Robert
Sent from my iPhone
It is confusing if you think of the relationship at database level (which I am often guilty of). If you think about the objects in memory and oop design then it is perfectly reasonable for one object not to know about a relationship, unless you tell it.
-- sent by a little green robot
--