RE: 1:n deletion problem

From: Craig Miskell (cmiskel..lbatross.co.nz)
Date: Tue Jan 14 2003 - 19:56:04 EST

  • Next message: Andrus: "RE: 1:n deletion problem"

    Ugh... not good. Something seroiusly not right is happening - your code
    seems fine, so it must be something else not happening right within
    Cayenne.
    In my time honoured tradition of jumping to random conclusions: Is it
    possible that one of the ProjectUser objects hasn't been committed yet?
    I'm trying to picture a situation where the query would be generated as
    such, and the only thing I can think of is that the object doesn't have
    an ObjectId yet. It's a long shot though.

    If not, would you be able to send us (privately if need be) the full
    cayenne model, and as small a snapshot of the code as possible that will
    reproduce the problem?
    And just to confirm, you're running this against MySql, right?
    Version? Is this a webapp, gui, commandline, something else? (Might be
    relevant, might not).

    Craig

    On Wed, 2003-01-15 at 14:42, Fan, Bill (AP - Australia) wrote:
    > Craig,
    >
    > I tried Andrus's code and yours, both of them generated the "DELETE FROM
    > PROJECTUSERS" statement.
    >
    > 1. Here is the code statements related:
    > =======================================
    >
    > // get the user
    > Users users = getUsers(ctxt, login);
    > // get the projectusers list
    > List projectusers = users.getProjectusersArray();
    > // remove them
    > for (int i=0; i<projectuses.size(); i++)
    > {
    > Projectusers obj = (Projectusers)projectusers.get(i);
    >
    > // I've tried to commented out this line, it has the same result
    > users.removeFromProjectusersArray(obj);
    >
    > ctxt.deleteObject(obj);
    > }
    > // commit the changes
    > ctxt.commitChanges(Level.WARN);
    >
    >
    > 2. The db/object relationship from the datamap xml file:
    > ========================================================
    >
    > <db-relationship name="projectusersArray" source="USERS"
    > target="PROJECTUSERS" toDependentPK="false" toMany="true">
    > <db-attribute-pair source="UserId" target="UserId"/>
    > </db-relationship>
    >
    >
    >
    > <obj-relationship name="projectusersArray" source="Users"
    > target="Projectusers" toMany="true" deleteRule="Nullify">
    > <db-relationship-ref source="USERS" target="PROJECTUSERS"
    > name="projectusersArray"/>
    > </obj-relationship>
    >
    >
    > 3. The related output from the tomcat running console:
    > ======================================================
    > INFO
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:54) : ****Inside UpdateProjectuserAction.update()
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logQueryStart(QueryLogger.java:30
    > 0) : --- will run 1 query.
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logQuery(QueryLogger.java:245) :
    > SELECT t0.Email, t0.Firstname, t0.Fullname, t0.Lastname, t0.Login,
    > t0.Password, t0.Status, t0.UserId FROM dbo.USERS t0 WHERE t0.Login = ?
    > [params: 'david']
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logSelectCount(QueryLogger.java:2
    > 70) : === returned 1 row. - took 10 ms.
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:109) : users.getFirstname()=David
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:110) : users.getLastname()=Colley
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:111) : users.getLogin()=david
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:126) : =========>
    > ((Projectusers)projectusersArray.get(i)).getUserid()=260
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:127) : =========>
    > ((Projectusers)projectusersArray.get(i)).getProjectid()=1
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:128) : =========> ((Projectusers)projectusersArray.get(i)).getRoleid()=2
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:126) : =========>
    > ((Projectusers)projectusersArray.get(i)).getUserid()=260
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:127) : =========>
    > ((Projectusers)projectusersArray.get(i)).getProjectid()=1
    > DEBUG
    > issuemanager.action.UpdateProjectUserAction.update(UpdateProjectUserAction.j
    > ava:128) : =========> ((Projectusers)projectusersArray.get(i)).getRoleid()=2
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logQueryStart(QueryLogger.java:30
    > 0) : --- will run 1 query.
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logQuery(QueryLogger.java:245) :
    > DELETE FROM dbo.PROJECTUSERS
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logUpdateCount(QueryLogger.java:2
    > 78) : === updated 5 rows.
    > WARN
    > org.objectstyle.cayenne.access.QueryLogger.logCommitTransaction(QueryLogger.
    > java:283) : +++ transaction committed.
    >
    >
    >
    >
    > Is there anything I did wrong here?
    >
    >
    > Thanks so much for your help!
    >
    > Bill
    >
    >
    >
    >
    >
    >
    >
    > -----Original Message-----
    > From: Craig Miskell [mailto:cmiskel..lbatross.co.nz]
    > Sent: Wednesday, January 15, 2003 10:23 AM
    > To: cayenne-use..bjectstyle.org
    > Subject: RE: 1:n deletion problem
    >
    >
    > Nope, it'll just delete obj, which is the current ProjectUser (from the
    > projectsuserss array, which is popuplated from
    > user.getProjectusersArray()
    >
    > Craig
    > On Wed, 2003-01-15 at 14:11, Fan, Bill (AP - Australia) wrote:
    > >
    > > Ooops, Andrus,
    > >
    > > The line of ctxt.deleteObject(obj) will remove all the records in the
    > > ProjectUsers table regardless what record the obj is linked to.
    > >
    > >
    > >
    > > Bill
    > >
    > >
    > >
    > >
    > > -----Original Message-----
    > > From: Andrus Adamchik [mailto:andru..bjectstyle.org]
    > > Sent: Wednesday, January 15, 2003 9:22 AM
    > > To: cayenne-use..bjectstyle.org
    > > Subject: Re: 1:n deletion problem
    > >
    > >
    > > Craig, Bill,
    > >
    > > I think there is a solution that does not involve the nightly build (Or am
    > > I missing something in this discussion?). Simply delete an object after
    > > unsetting relationship:
    > >
    > > for(int i=0; i<projectuserss.size(); i++) {
    > > Projectuser obj = (Projectusers)projectuserss.get(i);
    > > user.removeFromProjectusersArray(obj);
    > >
    > > // !!! This Line Is Added
    > > ctxt.deleteObject(obj);
    > > }
    > > ctxt.commitChanges(Level.WARN);
    > >
    > >
    > >
    > > Andrus
    > >
    > > > Easy. Simply removing the projectuser from the user will not trigger
    > > > deletion. The behaviour you are seeing is quite correct (you may be
    > > > used to WebOBjects/EOF, where such relationships can be set up (Owns
    > > > destination) such that removing does delete the destination object.
    > > > Cayenne doesn't have that (yet... don't know if it will, we'll have to
    > > > discuss that on the dev list).
    > > >
    > > > Now to the solution:
    > > > You say you're using release alpha-5-1. If you open the model in
    > > > CayenneModeller, you may notice that the ObjRelationships have an
    > > > additional column on the right of their specification, titled "Delete
    > > > rule". In a5-1, the actual implementation of that is disabled (some
    > > > bugs that mucked up constraints ... tested initially on mysql, committed
    > > > to cvs, then discovered it failed on Oracle which actually has
    > > > constraints. Bah humbug).
    > > >
    > > > If you get the nightly build, the implementation has been sorted out.
    > > > So, what you'd do is set the relationship from ProjectUser to User to be
    > > > Nullify (actually, that's the default). Then, your for loop would look
    > > > like this (parentheses might be wrong):
    > > >
    > > > for (int i=0; i<projectuserss.size(); i++) {
    > > > ctxt.deleteObject(((Projectusers)projectuserss.get(i)));
    > > > }
    > > >
    > > > The delete rule is fired when you delete the ProjectUser. It looks at
    > > > all of the relationships from ProjectUser to other ObjEntities. For
    > > > nullify, it looks at the reverse relationship (user projectusersArray in
    > > > this case). If it's toOne, it is set to null. If to-Many (your case),
    > > > the object being deleted will be removed from that relationship. If
    > > > there is no reverse relationship, nothing happens. The other rules are
    > > > Cascade (if you set this relationship to cascade, the User would be
    > > > deleted) and Deny, which throws an exception when you try to delete if
    > > > the destination has any objects.
    > > >
    > > > Let me know if you need more help on this.. I'm planning on writing
    > > > docos on it, but haven't yet had the time (actually, more like "not had
    > > > the inclination", but lack of time sounds better :-))
    > > >
    > > > Craig Miskell
    > > >
    > > >
    > > > On Wed, 2003-01-15 at 12:27, Fan, Bill (AP - Australia) wrote:
    > > >> Hi All,
    > > >>
    > > >> I'm having problem to use the X.removeFromYArray(y) function to delete
    > > >> the 1:n relationship records in the database. I'm using tomcat 4.1.17
    > > >> + Struts 1.1 + Cayenne-1.0a5-1.
    > > >>
    > > >> It is a project issue management system. There are 4 tables in the
    > > >> user management section - Project, Users, Role & ProjectUsers. The
    > > >> tables are defined as following (in brief):
    > > >>
    > > >> Project:
    > > >> ProjectId int PK
    > > >> ProjectName varchar(100)
    > > >>
    > > >> Users: (oops, can't use User in MSSQL, don't get confused below... )
    > > >> UserId int PK
    > > >> Login varchar(50)
    > > >> Password varchar(20)
    > > >>
    > > >> Role:
    > > >> RoleId int PK
    > > >> RoleDesc varchar(50)
    > > >>
    > > >> ProjectUsers:
    > > >> ProjectId int FK
    > > >> UserId int FK
    > > >> RoleId int FK
    > > >>
    > > >> ProjectUsers table holds all the information how the user can access
    > > >> the system. When I come to the section to edit/modify the user roles,
    > > >> I need to delete the records in this table for a user related to a
    > > >> particular project, then add the new ones. The logic related to the
    > > >> deletion process is as following:
    > > >>
    > > >> // 1. get the user object
    > > >> Users users = getUsers(ctxt, login);
    > > >>
    > > >> // 2. get the all related projectuser objects(regardless what
    > > >> project for now)
    > > >> List projectuserss = user.getProjectusersArray();
    > > >>
    > > >> // 3. iterating through the projectusers list and remove them: for
    > > >> (int i=0; i<projectuserss.size(); i++)
    > > >>
    > > >> user.removeFromProjectusersArray((Projectusers)projectuserss.get(i));
    > > >>
    > > >> // 4. finally, commit the changes
    > > >> ctxt.commitChanges(Level.WARN);
    > > >>
    > > >> No matter what I did, just can't see the DELETE statement generated by
    > > >> Cayenne from the tomcat running console, and the database records are
    > > >> not removed obviously.
    > > >>
    > > >> The users object and the related projectuserss list returned by the
    > > >> statements can be verified they are all correct. I've tried to set the
    > > >> users object consistence state by using
    > > >> users.setPersistenceState(PersistenceStte.MODIFIED) right after I get
    > > >> the users object, eventhough it is not the case in the
    > > >> RemovePaintingFroGalleryAction example.
    > > >>
    > > >> On the other hand, the users.addToProjectusersArray(projectusers)
    > > >> function is working perfectly (I've added lot of duplicated records ;-
    > > >> )
    > > >>
    > > >>
    > > >> What I'm doing wrong here? Can anyone point me to the right direction?
    > > >>
    > > >>
    > > >> Thanks for your help!
    > > >>
    > > >> Bill
    > > >>
    > > >>
    > > >>
    > > >>
    > > >>
    > > >>
    > > >>
    > >
    > >
    >



    This archive was generated by hypermail 2.0.0 : Tue Jan 14 2003 - 19:52:46 EST