-->
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.  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: one-to-many (using XDoclet) question
PostPosted: Wed Jan 21, 2004 4:22 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
I am attempting to create a one-to-many relationship between 2 data objects using hibernate and xdoclet. I have been through much of the documentation, but still need some help.

I have 2 classes: Album and Image, both listed below (in part). The superclass contains the generated id. :

[quote]
/**
* @hibernate.class
* table="image"
* @hibernate.subclass
* discrimator-value="image"
*/
public class Image extends BaseDataObject
{

public Image(){}


/**
* @hibernate.many-to-one
* not_null="true"
*
*/
public Album getAlbum()
{
return album;
}

/**
* @hibernate.property
* column="description"
*
*
*/
public String getDescription()
{
return description;
}

/**
* @hibernate.property
* column="filename"
*
*
*/
public String getFilename()
{
return filename;
}

/**
* @hibernate.property
* column="owner"
*
*
*/
public String getOwner()
{
return owner;
}

/**
* @hibernate.property
* column="thumbnailFilename"
*
*
*/
public String getThumbnailFilename()
{
return thumbnailFilename;
}

/**
* @hibernate.property
* column="title"
*
*
*/
public String getTitle()
{
return title;
}


}
[/quote]

[quote]

import java.util.*;

/**
* @hibernate.class
* table="album"
* @hibernate.subclass
* discrimator-value="album"
*/
public class Album extends BaseDataObject
{

public Album(){}


/**
* @hibernate.property
* column="date"
*
*
*/
public String getDate()
{
return date;
}

/**
* @hibernate.property
* column="description"
*
*
*/
public String getDescription()
{
return description;
}

/**
* @hibernate.property
* column="owner"
*
*
*/
public String getOwner()
{
return owner;
}

/**
* @hibernate.property
* column="title"
*
*
*/
public String getTitle()
{
return title;
}


/**
* @hibernate.set
* lazy="true"
* cascade="all"
* inverse="true"
*
* @hibernate.collection-one-to-many
* class="com.sullins.data.Image"
*
* @hibernate.collection-key
* column="album_id"
*/
public Set getImages()
{
return images;
}

}

[/quote]

The following is the code I am using to save an Album instance:

[quote]

logger.debug( obj.toString() );
Transaction trans = hibernateSession.beginTransaction();
hibernateSession.save(obj);

Set images = obj.getImages();

hibernateSession.save( images );

logger.debug( "album has been saved" );
trans.commit();
[/quote]



and finally, the log file portion generated:

[quote]

####<saving [com.sullins.data.Album#<null>]>
####<processing cascades for: com.sullins.data.Album>
####<done processing cascades for: com.sullins.data.Album>
####<Wrapped collection in role: com.sullins.data.Album.images>
####<Inserting entity: com.sullins.data.Album (native id)>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: insert into album (date, description, owner, title) values (?, ?, ?, ?)
>
Hibernate: insert into album (date, description, owner, title) values (?, ?, ?, ?)
####<preparing statement>
####<Dehydrating entity: com.sullins.data.Album#null>
####<binding '21-0-2004' to parameter: 1>
####<binding 'I wonder how I should make paragraphs?' to parameter: 2>
####<binding 'bsullins' to parameter: 3>
####<binding 'The new title for it' to parameter: 4>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<closing statement>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: SELECT LAST_INSERT_ID()>
Hibernate: SELECT LAST_INSERT_ID()
####<preparing statement>
####<Natively generated identity: 0>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<closing statement>
####<processing cascades for: com.sullins.data.Album>
####<cascading to collection: com.sullins.data.Album.images>
####<cascading to saveOrUpdate()>
####<unsaved-value strategy NULL>
####<saveOrUpdate() previously saved instance with id: 0>
####<updating [com.sullins.data.Image#0]>
####<done processing cascades for: com.sullins.data.Album>

[/quote]

As a result, only the Album instance is saved, no Image instances. There is 1 image attached to the Album in this scenario.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 21, 2004 5:14 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Reread the Parent/Child relationship chapter of the reference guide and http://www.hibernate.org/Documentation/InsideExplanationOfInverseTrue

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 21, 2004 5:36 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
[quote="emmanuel"]Reread the Parent/Child relationship chapter of the reference guide and [url]http://www.hibernate.org/Documentation/InsideExplanationOfInverseTrue[/url][/quote]

I did, and I thought I had it right. Are you saying I should change the inverse="true" to false? I will reread to be sure of my assumptions.

Also, do I need to explicitly save both the album and the Set of images, or is there a way to just save the album and have it also save the contained images?

Thanks for your reply.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 21, 2004 6:08 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
bsullins wrote:
I did, and I thought I had it right. Are you saying I should change the inverse="true" to false? I will reread to be sure of my assumptions.

Yep, you don't have the other side, so false is required to save the association

bsullins wrote:
Also, do I need to explicitly save both the album and the Set of images, or is there a way to just save the album and have it also save the contained images?

The concept of saving the set is irrevelent. only object are saved in Hibernate.
Using cascade="all", a save of album will save every associated image. If you had used cascade="none", you'd have to save every image individually.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 21, 2004 7:51 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
Not sure what you mean by not having the other side. Image has a getAlbum method.


[quote="emmanuel"]Using cascade="all", a save of album will save every associated image. If you had used cascade="none", you'd have to save every image individually.[/quote]

I went ahead and set inverse to false, changed to cascade all, but still no luck. The log is the same. I think I am missing something....

I appreciate your help, thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 5:07 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
You mapped getAlbum => inverse="true" is good, sorry

Show the mapping and exact code (including obj build), don't do save(images) it's pointless.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 10:43 am 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
The album instance is saved everytime, but no image instances. Here is the storage code:

Code:
            logger.debug( obj.toString() );
            Transaction trans = hibernateSession.beginTransaction();
            hibernateSession.save(obj);


            logger.debug( "album has been saved" );
            trans.commit();


The source of the persistent object remains as in the first post. Here are the generated mapping files:

Code:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class
        name="com.sullins.data.Album"
        table="album"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="id"
            column="id"
            type="java.lang.Long"
        >
            <generator class="native">
            </generator>
        </id>

        <property
            name="date"
            type="java.lang.String"
            update="true"
            insert="true"
            column="date"
        />

        <property
            name="description"
            type="java.lang.String"
            update="true"
            insert="true"
            column="description"
        />

        <property
            name="owner"
            type="java.lang.String"
            update="true"
            insert="true"
            column="owner"
        />

        <property
            name="title"
            type="java.lang.String"
            update="true"
            insert="true"
            column="title"
        />

        <set
            name="images"
            lazy="true"
            inverse="true"
            cascade="all"
            sort="unsorted"
        >

              <key
                  column="album_id"
              />

              <one-to-many
                  class="com.sullins.data.Image"
              />
        </set>

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-Album.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>



Code:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class
        name="com.sullins.data.Image"
        table="image"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="id"
            column="id"
            type="java.lang.Long"
        >
            <generator class="native">
            </generator>
        </id>

        <many-to-one
            name="album"
            class="com.sullins.data.Album"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            column="album"
        />

        <property
            name="description"
            type="java.lang.String"
            update="true"
            insert="true"
            column="description"
        />

        <property
            name="filename"
            type="java.lang.String"
            update="true"
            insert="true"
            column="filename"
        />

        <property
            name="owner"
            type="java.lang.String"
            update="true"
            insert="true"
            column="owner"
        />

        <property
            name="thumbnailFilename"
            type="java.lang.String"
            update="true"
            insert="true"
            column="thumbnailFilename"
        />

        <property
            name="title"
            type="java.lang.String"
            update="true"
            insert="true"
            column="title"
        />

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-Image.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>



and here is the log output:

Code:
####<saving [com.sullins.data.Album#<null>]>
####<processing cascades for: com.sullins.data.Album>
####<done processing cascades for: com.sullins.data.Album>
####<Wrapped collection in role: com.sullins.data.Album.images>
####<Inserting entity: com.sullins.data.Album (native id)>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: insert into album (date, description, owner, title) values (?, ?, ?, ?)
>
Hibernate: insert into album (date, description, owner, title) values (?, ?, ?, ?)
####<preparing statement>
####<Dehydrating entity: com.sullins.data.Album#null>
####<binding '22-0-2004' to parameter: 1>
####<binding 'I wonder how I should make paragraphs?' to parameter: 2>
####<binding 'bsullins' to parameter: 3>
####<binding 'The new title for it' to parameter: 4>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<closing statement>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: SELECT LAST_INSERT_ID()>
Hibernate: SELECT LAST_INSERT_ID()
####<preparing statement>
####<Natively generated identity: 0>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<closing statement>
####<processing cascades for: com.sullins.data.Album>
####<cascading to collection: com.sullins.data.Album.images>
####<cascading to saveOrUpdate()>
####<unsaved-value strategy NULL>
####<saveOrUpdate() previously saved instance with id: 0>
####<updating [com.sullins.data.Image#0]>
####<done processing cascades for: com.sullins.data.Album>


Thanks again, I know this is probably something trivial, but I do appreciate the help.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 10:59 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Why do you say image is not inserted,
it seems to be alreadfy in DB with id 0, so updated, not inserted.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 12:33 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
That is what is so confusing to me. There is actually nothing in that table before the save, and nothing after. The album table gets 1 row inserted, the image table has nothing. I clear out both tables between tests to be sure.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 1:24 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Show the simpliest version of your code, mapping, ...

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 3:10 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
emmanuel wrote:
Show the simpliest version of your code, mapping, ...


Sorry, I don't know what you want...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 6:05 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Sorry, I read too fast.
Try to do the following:
set show_sql to true in your hibernate config file
clear all data in your DB
try to add a simple image using saveOrUpdate, and check the success.
try to save an album having images and check sucess.
Your mapping seems fine.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 6:36 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
Ok, I switched to a saveOrUpdate() call, and it appears to have gotten a little further. However, this time, neither the album or the image got saved. Here is the code for the save:

Code:

            logger.debug( obj.toString() );
            Transaction trans = hibernateSession.beginTransaction();
            hibernateSession.saveOrUpdate(obj);
            logger.debug( "obj has been saved" );
            trans.commit();


and the log:

Code:
####<begin>
####<unsaved-value strategy NULL>
####<saveOrUpdate() previously saved instance with id: 0>
####<updating [com.sullins.data.Album#0]>
####<collection dereferenced while transient [com.sullins.data.Album.images#0]>
####<processing cascades for: com.sullins.data.Album>
####<cascading to collection: com.sullins.data.Album.images>
####<cascading to saveOrUpdate()>
####<unsaved-value strategy NULL>
####<saveOrUpdate() previously saved instance with id: 0>
####<updating [com.sullins.data.Image#0]>
####<done processing cascades for: com.sullins.data.Album>
####<obj has been saved>
####<commit>
####<flushing session>
####<processing cascades for: com.sullins.data.Album>
####<cascading to collection: com.sullins.data.Album.images>
####<cascading to saveOrUpdate()>
####<saveOrUpdate() persistent instance>
####<done processing cascades for: com.sullins.data.Album>
####<Flushing entities and processing referenced collections>
####<Wrapped collection in role: com.sullins.data.Album.images>
####<Updating entity: [com.sullins.data.Album#0]>
####<Collection found: [com.sullins.data.Album.images#0], was: [<unreferenced>]>
####<Updating entity: [com.sullins.data.Image#0]>
####<Processing unreferenced collections>
####<Scheduling collection removes/(re)creates/updates>
####<Flushed: 0 insertions, 2 updates, 0 deletions to 3 objects>
####<Flushed: 1 (re)creations, 0 updates, 1 removals to 1 collections>
####<executing flush>
####<Updating entity: com.sullins.data.Album#0>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: update album set date=?, description=?, owner=?, title=? where id=?>
Hibernate: update album set date=?, description=?, owner=?, title=? where id=?
####<preparing statement: update album set date=?, description=?, owner=?, title=? where id=?>
####<Dehydrating entity: com.sullins.data.Album#0>
####<binding '22-0-2004' to parameter: 1>
####<binding 'I wonder how I should make paragraphs?' to parameter: 2>
####<binding 'bsullins' to parameter: 3>
####<binding 'The new title for it' to parameter: 4>
####<binding '0' to parameter: 5>
####<Adding to batch>
####<Updating entity: com.sullins.data.Image#0>
####<Executing batch size: 1>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<recaching>
####<total checked-out statements: 0>
####<checked out: []>
####<about to open: 0 open PreparedStatements, 0 open ResultSets>
####<prepared statement get: update image set album_id=?, description=?, filename=?, owner=?, thumbn
ailFilename=?, title=? where id=?>
Hibernate: update image set album_id=?, description=?, filename=?, owner=?, thumbnailFilename=?, tit
le=? where id=?
####<preparing statement: update image set album_id=?, description=?, filename=?, owner=?, thumbnail
Filename=?, title=? where id=?>
####<Dehydrating entity: com.sullins.data.Image#0>
####<binding '0' to parameter: 1>
####<binding 'This is the first image of the test' to parameter: 2>
####<binding 'testimage.gif' to parameter: 3>
####<binding 'bsullins' to parameter: 4>
####<binding null to parameter: 5>
####<binding 'the first image' to parameter: 6>
####<binding '0' to parameter: 7>
####<Adding to batch>
####<Executing batch size: 1>
####<done closing: 0 open PreparedStatements, 0 open ResultSets>
####<recaching>
####<total checked-out statements: 0>
####<checked out: []>
####<post flush>
####<transaction completion>


should I be doing a flush() before the commit?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 6:53 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Hibernate guess the objects need to be updated, not saved.
I think you use a primitive type as id => set unsaved-value="0"
or have a broken setter/getter of id.
Check unsaved-value in the reference guide

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2004 6:58 pm 
Newbie

Joined: Wed Jan 21, 2004 2:56 pm
Posts: 9
I have my getId() and setId() in a baseclass, would that effect it?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next

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.