-->
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.  [ 5 posts ] 
Author Message
 Post subject: composition mapping with inheritance
PostPosted: Thu Jul 28, 2005 6:10 pm 
Newbie

Joined: Thu Jul 28, 2005 5:59 pm
Posts: 5
Location: Rio de Janeiro, Brazil
Hi!

I don't have experience with Hibernate and I've got some problems with the following mapping.

The domain model description:

I want to store html templates.
The Template class has a set of Field objects.
There is an abstract class Field and some subclasses (TextField, SelectField).
Eventually, a field has a set of FieldOption objects.

I would like to do, for example:

Code:

Template template = new Template();
template.setId(...);
template.setName(...);
template.setDeleted(...);

TextField tField = new TextField();
tField.setId(...);
tField.setName(...);
tField.setSize(...);

template.getFields().add(tField);

// lets not consider the select field example, which has field options

HibernateUtil.beginTransaction();
HibernateUtil.currentSession().saveOrUpdate(template);
HibernateUtil.commitTransaction();



... and I'd have all the structure persisted. Is it possible?
It's a composition relationship, the fields don't exist without a template.

I don't know if the mapping is wrong or anything else... :(
When a run a test, it raised an exception:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1

Watching the debug log, I see the insert for the template, but after, an update for the field... (see below)

Code:

18:48:27,437 DEBUG SQL:297 - insert into T_TEMPLATE (name, deleted, id) values (?, ?, ?)
...
18:48:27,484 DEBUG SQL:297 - update T_FIELD set id_template=? where id=?



Does anyone have any tips about this kind of mapping ?

Mapping documents:

Code:

<hibernate-mapping>

   <class name="br.ufrj.cos.reuse.biblioteca.template.Template" table="T_TEMPLATE">
          <id name="id" type="string" column="id" unsaved-value="0">
              <generator class="assigned"/>
           </id>           
      <property name="name" column="name" type="string"/>
      <property name="deleted" column="deleted" type="boolean"/>           
      <set name="fields">
         <key column="id_template" not-null="true"/>
         <one-to-many class="br.ufrj.cos.reuse.biblioteca.template.field.Field"/>
      </set>      
   </class>

   <class name="br.ufrj.cos.reuse.biblioteca.template.field.Field" table="T_FIELD">
          <id name="id" type="string" column="id" unsaved-value="0">
              <generator class="assigned"/>
           </id>           
      <property name="name" column="name" type="string"/>
           <property name="required" column="required" type="boolean"/>           
      <set name="options">
         <key column="id_field" not-null="true"/>
         <one-to-many class="br.ufrj.cos.reuse.biblioteca.template.field.FieldOption"/>
      </set>
         
           <joined-subclass name="br.ufrj.cos.reuse.biblioteca.template.field.TextField" table="T_FIELD_TEXT">
               <key column="id"/>
               <property name="size" column="size" type="string"/>
           </joined-subclass>       
     
           <joined-subclass name="br.ufrj.cos.reuse.biblioteca.template.field.SelectField" table="T_FIELD_SELECT">
               <key column="id"/>      
               <property name="size" column="size" type="string"/>
               <property name="multiple" column="multiple" type="boolean"/>                       
           </joined-subclass>                                       
     
   </class>
   
   <class name="br.ufrj.cos.reuse.biblioteca.template.field.FieldOption" table="T_FIELD_OPTION">
          <id name="id" type="string" column="id" unsaved-value="0">
              <generator class="assigned"/>
           </id>           
      <property name="name" column="name" type="string"/>
           <property name="value" column="value" type="string"/>
           <property name="selected" column="selected" type="boolean"/>       
   </class>
     
</hibernate-mapping>



Hibernate version: 3

Name and version of the database you are using: MySQL 4.0.1


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2005 6:22 pm 
Regular
Regular

Joined: Thu May 26, 2005 2:08 pm
Posts: 99
Try something like this and see if it helps.

Code:
TextField tField = new TextField();
tField.setId(...);
tField.setName(...);
tField.setSize(...);

Set fieldSet = new HashSet();
fieldSet.add(tField);

template.setFields(fieldSet);



You also want to look up the "cascade" attribute in the docs and apply the appropriate cascade style to your set association.

Example: cascade="all,delete-orphan"


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2005 10:17 pm 
Newbie

Joined: Thu Jul 28, 2005 5:59 pm
Posts: 5
Location: Rio de Janeiro, Brazil
Hi, jdl

I tried your suggestion and also set the cascade (<set name="fields" cascade="all">), but it still doesn't work... :(

Actually, I don't know if I'm using the right mapping since I have a composition, but I didn't realize how to use the composite-element mapping, since the elements (fields) form an hiearchy (joined-subclasses).

Also, I don't know if the behavior I'm expecting is possible, that is, saving the hole tree of objects from the template (template, fields, options).

:(

The debug info is below:

23:05:14,250 DEBUG JDBCTransaction:81 - commit
23:05:14,250 DEBUG AbstractFlushingEventListener:49 - flushing session
23:05:14,250 DEBUG AbstractFlushingEventListener:99 - processing flush-time cascades
23:05:14,250 DEBUG Cascades:806 - processing cascade ACTION_SAVE_UPDATE for: br.ufrj.cos.reuse.biblioteca.template.Template
23:05:14,250 DEBUG Cascades:853 - cascade ACTION_SAVE_UPDATE for collection: br.ufrj.cos.reuse.biblioteca.template.Template.fields
23:05:14,250 DEBUG Cascades:152 - cascading to saveOrUpdate: br.ufrj.cos.reuse.biblioteca.template.field.Field
23:05:14,250 DEBUG AbstractSaveEventListener:385 - persistent instance of: br.ufrj.cos.reuse.biblioteca.template.field.Field
23:05:14,250 DEBUG DefaultSaveOrUpdateEventListener:99 - ignoring persistent instance
23:05:14,250 DEBUG DefaultSaveOrUpdateEventListener:136 - object already associated with session: [br.ufrj.cos.reuse.biblioteca.template.field.TextField#6055fa87c9053097012f66848e24f2b4]
23:05:14,250 DEBUG Cascades:871 - done cascade ACTION_SAVE_UPDATE for collection: br.ufrj.cos.reuse.biblioteca.template.Template.fields
23:05:14,250 DEBUG Cascades:831 - done processing cascade ACTION_SAVE_UPDATE for: br.ufrj.cos.reuse.biblioteca.template.Template
23:05:14,250 DEBUG Cascades:806 - processing cascade ACTION_SAVE_UPDATE for: br.ufrj.cos.reuse.biblioteca.template.field.TextField
23:05:14,250 DEBUG Cascades:853 - cascade ACTION_SAVE_UPDATE for collection: br.ufrj.cos.reuse.biblioteca.template.field.Field.options
23:05:14,250 DEBUG Cascades:871 - done cascade ACTION_SAVE_UPDATE for collection: br.ufrj.cos.reuse.biblioteca.template.field.Field.options
23:05:14,250 DEBUG Cascades:831 - done processing cascade ACTION_SAVE_UPDATE for: br.ufrj.cos.reuse.biblioteca.template.field.TextField
23:05:14,250 DEBUG AbstractFlushingEventListener:147 - dirty checking collections
23:05:14,250 DEBUG AbstractFlushingEventListener:164 - Flushing entities and processing referenced collections
23:05:14,265 DEBUG Collections:107 - Collection found: [br.ufrj.cos.reuse.biblioteca.template.Template.fields#6055fa58c905309700253498800ac2d3], was: [<unreferenced>] (initialized)
23:05:14,265 DEBUG WrapVisitor:82 - Wrapped collection in role: br.ufrj.cos.reuse.biblioteca.template.field.Field.options
23:05:14,265 DEBUG DefaultFlushEntityEventListener:119 - Updating entity: [br.ufrj.cos.reuse.biblioteca.template.field.TextField#6055fa87c9053097012f66848e24f2b4]
23:05:14,265 DEBUG Collections:107 - Collection found: [br.ufrj.cos.reuse.biblioteca.template.field.Field.options#6055fa87c9053097012f66848e24f2b4], was: [<unreferenced>] (initialized)
23:05:14,265 DEBUG AbstractFlushingEventListener:200 - Processing unreferenced collections
23:05:14,265 DEBUG AbstractFlushingEventListener:214 - Scheduling collection removes/(re)creates/updates
23:05:14,281 DEBUG AbstractFlushingEventListener:76 - Flushed: 1 insertions, 1 updates, 0 deletions to 2 objects
23:05:14,281 DEBUG AbstractFlushingEventListener:82 - Flushed: 2 (re)creations, 0 updates, 1 removals to 2 collections
23:05:14,281 DEBUG Printer:80 - listing entities:
23:05:14,281 DEBUG Printer:87 - br.ufrj.cos.reuse.biblioteca.template.Template{deleted=false, fields=[br.ufrj.cos.reuse.biblioteca.template.field.Field#6055fa87c9053097012f66848e24f2b4], name=abc, id=6055fa58c905309700253498800ac2d3}
23:05:14,281 DEBUG Printer:87 - br.ufrj.cos.reuse.biblioteca.template.field.TextField{required=true, size=12, name=textfield, id=6055fa87c9053097012f66848e24f2b4, options=[]}
23:05:14,281 DEBUG AbstractFlushingEventListener:264 - executing flush
23:05:14,281 DEBUG BasicEntityPersister:1744 - Inserting entity: [br.ufrj.cos.reuse.biblioteca.template.Template#6055fa58c905309700253498800ac2d3]
23:05:14,281 DEBUG AbstractBatcher:259 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
23:05:14,281 DEBUG SQL:297 - insert into T_TEMPLATE (name, deleted, id) values (?, ?, ?)
23:05:14,281 DEBUG AbstractBatcher:348 - preparing statement
23:05:14,375 DEBUG BasicEntityPersister:1536 - Dehydrating entity: [br.ufrj.cos.reuse.biblioteca.template.Template#6055fa58c905309700253498800ac2d3]
23:05:14,375 DEBUG StringType:56 - binding 'abc' to parameter: 1
23:05:14,375 DEBUG BooleanType:56 - binding 'false' to parameter: 2
23:05:14,375 DEBUG StringType:56 - binding '6055fa58c905309700253498800ac2d3' to parameter: 3
23:05:14,375 DEBUG AbstractBatcher:28 - Adding to batch
23:05:14,375 DEBUG AbstractBatcher:55 - Executing batch size: 1
23:05:14,375 DEBUG AbstractBatcher:267 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
23:05:14,375 DEBUG AbstractBatcher:368 - closing statement
23:05:14,390 DEBUG BasicEntityPersister:1859 - Updating entity: [br.ufrj.cos.reuse.biblioteca.template.field.TextField#6055fa87c9053097012f66848e24f2b4]
23:05:14,390 DEBUG AbstractBatcher:259 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
23:05:14,390 DEBUG SQL:297 - update T_FIELD set name=?, required=? where id=?
23:05:14,390 DEBUG AbstractBatcher:348 - preparing statement
23:05:14,421 DEBUG BasicEntityPersister:1536 - Dehydrating entity: [br.ufrj.cos.reuse.biblioteca.template.field.TextField#6055fa87c9053097012f66848e24f2b4]
23:05:14,421 DEBUG StringType:56 - binding 'textfield' to parameter: 1
23:05:14,421 DEBUG BooleanType:56 - binding 'true' to parameter: 2
23:05:14,421 DEBUG StringType:56 - binding '6055fa87c9053097012f66848e24f2b4' to parameter: 3
23:05:14,421 DEBUG AbstractBatcher:28 - Adding to batch
23:05:14,421 DEBUG BasicEntityPersister:1859 - Updating entity: [br.ufrj.cos.reuse.biblioteca.template.field.TextField#6055fa87c9053097012f66848e24f2b4]
23:05:14,421 DEBUG AbstractBatcher:55 - Executing batch size: 1
23:05:14,437 ERROR AbstractBatcher:61 - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2005 10:32 pm 
Newbie

Joined: Thu Jul 28, 2005 5:59 pm
Posts: 5
Location: Rio de Janeiro, Brazil
I'am also posting the tables definitios:

Code:

CREATE TABLE T_TEMPLATE
(
id varchar(32) not null,
name varchar(255) not null,
deleted boolean not null default 0,
primary key (id)
) type=InnoDB;

CREATE TABLE T_FIELD
(
id varchar(32) not null,
name varchar(255) not null,
required boolean default 0,
id_template varchar(32) not null,
index (id),
index (id_template),
primary key (id),
foreign key (id_template) references T_TEMPLATE (id)
) type=InnoDB;

CREATE TABLE T_FIELD_TEXT
(
id varchar(32) not null,
size varchar(4) default '16',
index (id),
foreign key (id) references T_FIELD (id)
) type=InnoDB;

CREATE TABLE T_FIELD_SELECT
(
id varchar(32) not null,
size varchar(3) default '1',
multiple boolean default 0,
index (id),
foreign key (id) references T_FIELD (id)
) type=InnoDB;

CREATE TABLE T_FIELD_OPTION
(
id varchar(32) not null,
name varchar(255) not null,
value varchar(255) not null,
selected boolean default 0,
id_field varchar(32) not null,
primary key (id),
index (id_field),
foreign key (id_field) references T_FIELD (id)
) type=InnoDB;



Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2005 11:48 pm 
Newbie

Joined: Thu Jul 28, 2005 5:59 pm
Posts: 5
Location: Rio de Janeiro, Brazil
Humm... I think I found a solution.

After a more careful reading of Users FAQ, I noticed that the problems might be associated with my assigned id generation declaration.

I was using an IdGenerator to create string ids as primary keys. I changed them to integer ids and changed the table to use identity id generation (mysql auto_increment) and it worked (also using not-null="true" in the key column property of my one-to-many association).

The FAQ says I could also use assigned id generation since I set the unsaved-value to "undefined" but it would cost another database call, I guest, to determine if the instance is new or detached :/

I wouldn't like to use mysql auto_increment pk columns, but I think now it's time for me to study a little more before flooding the forums ! :)

best regards.


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