-->
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.  [ 13 posts ] 
Author Message
 Post subject: Delete error. One to Many relation. Child has composite id
PostPosted: Tue Nov 18, 2003 4:11 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
I was wondering why an UPDATE is called when cascade-deleting a child record on a uni-directional one-to-many relationship. Why doesn't it call a DELETE? Does it UPDATE the parent ID to null then DELETE (I've never gotten far enough to tell :)? Is there a way of avoiding this?

I know that the DELETE will work if I change the relationship to bi-directional. But since everything else is working (and makes sense) as a one-to-many uni-directional relationship I'd hate to change it. Please tell me the answer is something simple :)

I have the following one-to-many mapping:
Code:
<hibernate-mapping>

    <!-- Season -->
   <class name="com.fgl.ina.mastertables.seasons.Season" table="season">

      <id name="seasonID" column="season_ID" type="int">
         <generator class="identity"/>
      </id>

      <property name="activeIndicator" column="active_indicator" type="boolean"/>

      <map name="seasonDescriptions" lazy="false" cascade="all-delete-orphan" table="season_description">
         <key column="season_ID"/>
         <index column="locale" type="string"/>
         <one-to-many class="com.fgl.ina.mastertables.seasons.SeasonDescription"/>
      </map>

   </class>

   <!-- Season's Description -->
   <class name="com.fgl.ina.mastertables.seasons.SeasonDescription" table="season_description" >
      <composite-id unsaved-value="none">
            <key-property name="ID" column="season_ID"/>
            <key-property name="language" column="locale" type="string"/>
      </composite-id>
      <property name="description" column="description" type="string"/>
   </class>

</hibernate-mapping>


Here is my code in a DispatchAction for delete:
Code:
    public ActionForward delete (ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        ActionErrors errors = new ActionErrors();

        SeasonForm seasonForm = (SeasonForm)form;
        Season season = new Season(seasonForm.getSeasonID());
        try{
            DataAccessService.delete(PersistanceFilter.getSession(), season);
        }catch (Exception e){
            errors.add("error", new ActionError("seasonform.error.delete"));
        }
        if(!errors.isEmpty()){
            saveErrors(request, errors);
            return (mapping.getInputForward());
        }
        return (mapping.findForward("success"));
    }

The delete method is very simple:
Code:
   public static void delete(Session session, Object obj) throws HibernateException {
      session.delete(obj);
      session.flush();
   }


Clicking Delete in the JSP produces the following error message:
Code:
Hibernate: update season_description set season_ID=null, locale=null where season_ID=?

Severe: [SQLServer JDBC Driver]Cannot insert the value NULL into column 'locale', table 'INA.dbo.season.description'; column does not allow nulls. UPDATE fails.


My colleague wrote the following post but since no one answered and we are still experiencing the problem I am re-posting (about my own code).

http://forum.hibernate.org/viewtopic.php?t=924490

Thank you for any help.
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 18, 2003 6:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Please read "parent/child relationship" doco. You need to map your collection as inverse="true".


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 11:19 am 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
I'm sorry, Gavin. I have read the documentation, now I'm just trying to understand the documentation. Trust me, I would not be posting to the site without having read the documentation, I would be way to scared:).

The way I read the documentation I thought you had to have a bi-directional relationship when using inverse=true. Feel free to tell me to change to bi-directional if that's my problem. I would just rather avoid it so I don't have to rewrite anything else. I have a composite key in the child, part of which is a foreign key to the parent, and I know that makes things more complicated.

I added inverse=true and now I get the following batch errors.

Code:
Could not synchronize database state with session

HibernateException: Batch update row count wrong: 0


Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 11:27 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
Trust me, I would not be posting to the site without having read the documentation, I would be way to scared:).


Excellent. The evil-hard-ass-gavin persona is working ;)


Quote:
I thought you had to have a bi-directional relationship when using inverse=true. Feel free to tell me to change to bi-directional if that's my problem


If you want the not-null constraint, you need the association to be bidirectional. not-null constraint = must use Parent/Child pattern

Quote:
I have a composite key in the child, part of which is a foreign key to the parent, and I know that makes things more complicated.



ah perhaps slightly more complicated.....but still doable.



P.S. If you are using Hibernate 2.1, consider using a composite-element mapping. It seems to suit your case....


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 1:38 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
Thanks, we are using the 2.2 but were reading the 2.02 documentation so that didn't help any. Now have latest docs and I will look at composite-index.

Thanks,
Ursula

_________________
Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 4:32 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
Oops, I will look at composite-element

_________________
Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 8:44 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
I have mapped the season/season description as follows:
Code:
   <class name="com.fgl.ina.mastertables.seasons.Season" table="season">

      <id name="seasonID" column="season_ID" type="int" unsaved-value="0" >
         <generator class="identity"/>
      </id>

      <property name="activeIndicator" column="active_indicator" type="boolean"/>

      <map name="seasonDescriptions" lazy="false" cascade="all-delete-orphan" table="season_description" >
         <key column="season_ID"/>
         <index column="locale" type="string"/>
         <composite-element class="com.fgl.ina.mastertables.seasons.SeasonDescription" >

            <property name="description" column="description"/>
         </composite-element>

      </map>

   </class>


Ran a test. I can read/create seasons no problem. But delete issued delete statements for each table, no errors but nothing happened. The records still exist in the table.

Here is a snippet from the testcase:
Code:
      boolean cleanupFailed = false;
      try{
         session.delete(loadedSeason);
         session.flush();
      }catch(Exception e){
         cleanupFailed = true;
      }finally{
         session.close();
      }


The output is as follows:
Code:
Hibernate: delete from season_description where season_ID=?
Hibernate: delete from season where season_ID=?
Nov 19, 2003 5:35:55 PM net.sf.hibernate.impl.SessionFactoryImpl close
INFO: closing
Nov 19, 2003 5:35:55 PM net.sf.hibernate.connection.DriverManagerConnectionProvider close
INFO: cleaning up connection pool: jdbc:JSQLConnect://database:1433;databaseName=dbName

_________________
Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 8:45 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Looks like you don't commit the transaction.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 8:51 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
gavin wrote:
Looks like you don't commit the transaction.


I flush() right after the delete() call.

I read in the docs that:
Quote:
From time to time the Session will execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in memory. This process, flush, occurs by default at the following points
...
from Session.flush()


This does not commit the transaction?

[/quote]

_________________
Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 8:55 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Nope.

Check the FAQ.

If you want flush-and-commit-all-in-one, you must use the Transaction API.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 12:21 pm 
Newbie

Joined: Wed Nov 12, 2003 5:38 pm
Posts: 7
Location: Alberta, Canada
I've modified the delete function and added a transaction and it's working now (of course!). Thanks very much for your help. The composite-element was exactly what I needed.

The 'evil-hard-ass-gavin persona' barely showed :)

_________________
Thanks,
Ursula


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 12:33 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
:->


Good luck.


Top
 Profile  
 
 Post subject: One more question...
PostPosted: Tue Nov 25, 2003 1:16 pm 
Senior
Senior

Joined: Sun Aug 31, 2003 3:14 pm
Posts: 151
Location: Earth (at the moment)
With the mappings:
Code:
    <class name="com.fgl.ina.mastertables.seasons.Season" table="season">
        <id name="seasonID" column="season_ID" type="int" unsaved-value="0">
            <generator class="identity"/>
        </id>
        <property name="activeIndicator" column="active_indicator" type="boolean"/>
        <map name="seasonDescriptions" lazy="true" table="season_description">
            <key column="season_ID"/>
            <index column="locale" type="string"/>
            <composite-element class="com.fgl.ina.mastertables.seasons.SeasonDescription">
                <property name="description" column="description"/>
            </composite-element>
        </map>
    </class>

    <class name="com.fgl.ina.mastertables.seasons.SeasonDescription" table="season_description">
        <composite-id>
            <key-many-to-one name="ID" column="season_ID" class="com.fgl.ina.mastertables.seasons.Season"/>
            <key-property name="language" column="locale" type="string"/>
        </composite-id>
        <property name="description" column="description" type="string"/>
    </class>

everything works fine to save/update/delete but the ID property of the SeasonDescription instance is not populated. It goes into the database just fine, but is not set in the persistent object when it is retrieved et. al.
I have a jsp tag that was making use of the ID property of the child to pick one to render from a list of them and so I am wondering if there is a way to get the ID property of the child populated automatically when loading the parent?
I can set it manually in the setter method for setting the children on the parent by looping through all of the children and populating the ID from the parent's ID but this seems like it should be a redundant hack.
What am I missing or is the ID property of the child not supposed to be set when using composite-element?

Thank-you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.