-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Is this the right way for cascade CRUD operations?
PostPosted: Mon Jun 27, 2005 2:10 am 
Beginner
Beginner

Joined: Fri Apr 29, 2005 10:57 pm
Posts: 41
Hibernate version: 3.0

Yes I do own Hibernate in Action and it does not really answer this question...

I have the following relationship between two objects: a Client and a Project. A client can have as many projects as he wants (one-to-many) and a project can have only one client as a parent (many-to-one).

Here are the .hbm.xml files:

Client:

Code:
...
    <class name="Client" table="clients">
   
       <cache usage="read-write"/>
   
        <id name="ID" column="ID" type="java.lang.Long">
            <generator class="native"/>
        </id>       
...
       
        <set name="projects" table="projects" lazy="true" cascade="all">
           <cache usage="read-write"/>
           <key column="clientID"/>
           <one-to-many class="org.ablogic.projects.Project"/>
        </set>

...


Here's Project:

Code:
...

    <class name="Project" table="projects">
   
       <cache usage="read-write"/>
   
        <id name="ID" column="ID" type="java.lang.Long">
            <generator class="native"/>
        </id>
       
        <many-to-one name="client" class="org.ablogic.clients.Client" column="clientID" cascade="save-update" />

...


First question: are the "cascade" relationships correct? If my client is deleted, I want all the projects to be deleted as well - therefore it's "all".

If a project is deleted - I don't want to delete the client, but I still want to keep save/update going (even though it doesn't seem to work - I still have to delete objects manually).

So am I on the right track here?

Ok, now here's the CRUD actions in my struts action file:

Code:
public class ProjectCRUDAction extends DispatchAction
{
   public ActionForward create( ActionMapping mapping, ActionForm aform, HttpServletRequest request,
         HttpServletResponse response )
   {
      ProjectForm form = (ProjectForm)aform;
      Project project = new Project();
      form.copyTo(project);
      
      HibernateUtil.beginTransaction();
      HibernateUtil.getSession().save(project);
      project.getClient().getProjects().add(project);
      HibernateUtil.getSession().update(project.getClient());
      HibernateUtil.commitTransaction();
      

      request.setAttribute("project",project);
      
      return mapping.findForward("success");
   }
   
   public ActionForward edit( ActionMapping mapping, ActionForm aform, HttpServletRequest request,
         HttpServletResponse response )
   {
      ProjectForm form = (ProjectForm)aform;
      Project project = form.getProject();
      
      if (! project.getClient().equals(form.getClient()) )
         project.getClient().getProjects().remove(project);
      
      form.copyTo(project);
      project.getClient().getProjects().add(project);
      
      HibernateUtil.beginTransaction();
      HibernateUtil.getSession().update(project);
      HibernateUtil.getSession().update(project.getClient());
      HibernateUtil.commitTransaction();

      request.setAttribute("project",project);
      
      return mapping.findForward("success");
   }
   
   public ActionForward delete( ActionMapping mapping, ActionForm aform, HttpServletRequest request,
         HttpServletResponse response )
   {
      ProjectForm form = (ProjectForm)aform;
      Project project = form.getProject();
      project.getClient().getProjects().remove(project);
      
      HibernateUtil.beginTransaction();
      HibernateUtil.getSession().delete(project);
      HibernateUtil.getSession().update(project.getClient());
      HibernateUtil.commitTransaction();
      
      request.setAttribute("project",project);
      
      return mapping.findForward("success");
   }
}


So that's pretty muc creating/editing/deleting (according to the method name).

It seems that I'm doing an awful lot of extra work here - such as removing the project from the old client, and adding it to new client, and setting all those bi-directional references...

Well my question is - am I doing all the neccessary work, or is some of it redundant?

Thanks for your replies!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 27, 2005 11:32 pm 
Beginner
Beginner

Joined: Fri Apr 29, 2005 10:57 pm
Posts: 41
Hmm is there no support here?

I did buy the book and it doesn't answer a basic question like this, if this is not a place to get support, can somebody point me to it?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 28, 2005 8:26 am 
Regular
Regular

Joined: Thu Apr 29, 2004 5:08 pm
Posts: 56
Location: Montreal, Quebec, Canada
Ok, well, I see many problems with your mappings.

First, you should know about the inverse attribute for collections. Read on it. Second, you should read about Parent/Child relations, you would notice you need to use "all-delete-orphans" not simply "all"
Third, your code Client.addProject( Project project ) should look like this:


Code:
    project.setClient( this );
    projects.add( project );


This is definitevely covered in the book. There is a section for that specific use case right in the online doc.

_________________
- Frank


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 28, 2005 11:32 pm 
Beginner
Beginner

Joined: Fri Apr 29, 2005 10:57 pm
Posts: 41
Quote:
Ok, well, I see many problems with your mappings.


Be so nice and point them out? :)

Quote:
First, you should know about the inverse attribute for collections. Read on it.


I know what inverse does, it prevents Hibernate from updating the same table twice when you have bi-directional collections... In my case the collection isn't really bi-directional, since a client can have many projects (one-to-many) but a project can have only one client (many-to-one), and I can't use "inverse" in many-to-one associations.

Quote:
Second, you should read about Parent/Child relations, you would notice you need to use "all-delete-orphans" not simply "all"


I have read that stuff, and my understanding is when I use all-delete-orphan it would delete projects that don't have any clients... But if I specify "all", wouldn't that automatically delete project when a client is deleted?

Quote:
Third, your code Client.addProject( Project project ) should look like this:

project.setClient( this );
projects.add( project );


Well that's the same as what I do (except I don't do it inside my client):
Code:
...
form.copyTo(project);  // this does project.setClient( client )
...
project.getClient().getProjects().add(project);  // and this is the bi-direction
...


Quote:
This is definitevely covered in the book. There is a section for that specific use case right in the online doc.


Could you point to what I should read up on? So far everything works just fine, I just wanted to know if I have excessive code... According to your post I'm doing everything right, except our disagreement on the cascading options...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.