Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Problem using "union-subclass" (simple example)
PostPosted: Fri Aug 18, 2006 11:47 am 
Regular
Regular

Joined: Mon Jul 31, 2006 4:59 pm
Posts: 53
Hibernate 3.2
MySQL 5

I have the abstract class "Ressource" and the Sub-Class "Raum" and "Gegenstand". When i try to save it, this error shows up:

Code:
Exception in thread "main" org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: uebung9bPackage.Gegenstand



Here is the Ressource-Class:
Code:
public abstract class Ressource  {
   
   private long id;
   private String name;
   
   
   public long getId() {
      return id;
   }
   public void setId(long id) {
      this.id = id;
   }
   
   
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}



Ressource.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping>

   <class name="uebung9bPackage.Ressource" abstract="true" >
   
    <id name="id" column="id" type="long">
        <generator class="native"/>
    </id>
   
      
   <property name="name" column="name" type="string"/>

   
   <union-subclass name="uebung9bPackage.Raum" table="raum">
      <property name="gebaeude" column="gebaeude" type="string"/>
   </union-subclass>
   
   <union-subclass name="uebung9bPackage.Gegenstand" table="gegenstand">
      <property name="wert" column="wert" type="string"/>
   </union-subclass>
   
   
   </class>
   
</hibernate-mapping>



Class Gegenstand:
Code:
package uebung9bPackage;

public class Gegenstand extends Ressource{
   
   private String wert;

   public String getWert() {
      return wert;
   }

   public void setWert(String wert) {
      this.wert = wert;
   }

}



Class Raum:
Code:
package uebung9bPackage;

public class Raum extends Ressource{
   private String gebaeude;

   public String getGebaeude() {
      return gebaeude;
   }

   public void setGebaeude(String gebaeude) {
      this.gebaeude = gebaeude;
   }
}



Perhaps a database-error? Here are my tables:
Code:
CREATE TABLE `raum` (
`id` BIGINT NOT NULL ,
`name` VARCHAR( 50 ) NOT NULL ,
`gebaeude` VARCHAR( 50 ) NOT NULL
) TYPE = innodb;


Code:
CREATE TABLE `gegenstand` (
`id` BIGINT NOT NULL ,
`name` VARCHAR( 50 ) NOT NULL ,
`wert` VARCHAR( 50 ) NOT NULL
) TYPE = innodb;


Can someone help me please?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 20, 2006 8:34 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
You cannot use "native" generator with a table-per-class polymorphism strategy. Either change it to assigned, or switch your strategy.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 6:42 am 
Regular
Regular

Joined: Mon Jul 31, 2006 4:59 pm
Posts: 53
When i change in the Ressource.hbm.xml the generator to "assigned", this error shows up:

Code:
Exception in thread "main" org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1


I have turned in the hibernate.cfg.xml this option to true:
Code:
<property name="show_sql">true</property>


And i see this message:
Code:
Hibernate: insert into termin (kommentar, resid) values (?, ?)
Hibernate: update gegenstand set name=?, wert=? where id=?


after that the error shows up.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 8:30 am 
Regular
Regular

Joined: Tue Dec 14, 2004 5:21 am
Posts: 104
Location: india
this can occur because of the corrupt object . (object contain stale data) . try to use unsaved-value attribute of <id> to avoid this and also consider <version> and/or <timestamp>

hope this works out

_________________
sHeRiN
thanks for your ratings ...... :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 8:30 am 
Regular
Regular

Joined: Tue Dec 14, 2004 5:21 am
Posts: 104
Location: india
this can occur because of the corrupt object . (contain stale data) . try to use unsaved-value attribute of <id> to avoid this and also consider <version> and/or <timestamp>

hope this works out

_________________
sHeRiN
thanks for your ratings ...... :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 5:48 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Also don't forget that because the generator is now "assigned", you have to set the ID before saving it. If you set the ID to unsaved-value then save it, it won't work.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 8:23 pm 
Regular
Regular

Joined: Mon Jul 31, 2006 4:59 pm
Posts: 53
Thank you all for the answers. One question about the ID, how can i set this ID ? I must know which is the last ID in the database?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 9:25 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Yes. For a union subclass, where you want two tables to have non-overlapping IDs, you have two options:[list=1][*]Maintain a third table with nothing but IDs in it. Write an IdentifierGenerator class to insert a new row into the ID table and return it.
[*]Make the IDs of all unioned tables be composite, something along the lines of discriminator + sequencenum. Unfortunately this means you have another column in each table, which is going to have the same value for every row.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 9:32 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
D'Oh! Didn't mean to click submit. Anyway, back to that list (reposted for clarity):
  1. Maintain a third table with nothing but IDs in it. Write an IdentifierGenerator class to insert a new row into the ID table and return it.
  2. Make the IDs of all unioned tables be composite, something along the lines of discriminator + sequencenum. Unfortunately this means you have another column in each table, which is going to have the same value for every row.
  3. Use a sequence, if your DB supports it (best option).
If your DB doesn't have sequences, you'll have to implement an IdentifierGenerator that simulates sequences. Or you could use a GUID/UUID ID, that would be fine too, I guess. MySQL supports the generator class="guid". This avoids the issues you have when you use class="assigned", at the cost of a slightly larger ID column (guids are 16 bytes, and are usually converted to 36 character strings when loaded from the DB, which can be quite an expensive operation if you have a large table).

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 10:21 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Just spent a little time reading up on generators, and I notice that hilo and seqhilo generators implement case 1 in that list. So you don't need to write your own IdentifierGenerator, just use generator class="hilo" (MySQL doesn't support seqhilo).

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 6:16 am 
Regular
Regular

Joined: Mon Jul 31, 2006 4:59 pm
Posts: 53
Hello,

i have tried "hilo" and this error shows up:

Code:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not get or update next value

Caused by: java.sql.SQLException: Table 'uebung9b.hibernate_unique_key' doesn't exist

I dont have a "unique_key"-Table.


Ressource.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

   <class name="uebung9bPackage.Ressource" abstract="true" >
   
    <id name="id" column="id" type="long" unsaved-value="null">
        <generator class="hilo"/>
    </id>
   
      
   <property name="name" column="name" type="string"/>

   
   <union-subclass name="uebung9bPackage.Raum" table="raum">
      <property name="gebaeude" column="gebaeude" type="string"/>
   </union-subclass>
   
   <union-subclass name="uebung9bPackage.Gegenstand" table="gegenstand">
      <property name="wert" column="wert" type="string"/>
   </union-subclass>
   
   
   </class>
   
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 5:40 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Yes, hilo needs that extra table. If you don't want to create that table, you can still use one of the alternatives that I posted earlier: use composite-ids, use guids, or switch from using union-subclass to implicit polymorphism.

The implicit polymorphism option will defnitely be the easiest to get working, at the cost of duplicating chunks of mapping XML.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 6:34 pm 
Regular
Regular

Joined: Mon Jul 31, 2006 4:59 pm
Posts: 53
I will try it with "hilo". What columns did i need for this "unique_key"-table?

thanks for all answers guys! :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 7:02 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
All you need is a table with one column, whose contents are auto-generated by the DB. The easiest option in MySQL is to make the column an identity column. Then just tell hibernate the name of the table and column, as described in the ref docs section 5.1.4.2.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 7:09 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
I just looked at the algorithm and you don't even need an identity column. Any old int column will do.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 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.