-->
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.  [ 3 posts ] 
Author Message
 Post subject: SchemaExport column length problem
PostPosted: Tue Jan 13, 2004 10:28 am 
Newbie

Joined: Tue Jan 13, 2004 10:04 am
Posts: 1
I'm having some difficulties with the DDL generated by the SchemaExport tool. Using Hibernate 2.1.1, MySQL dialect.

Here's the setup. I have 3 mapping files(Item, GroupItemAttachment, GroupItemInclude ). Item is a class heirarchy which includes GroupItem as a joined-subclass. GroupItemAttachment and GroupItemInclude both map a many-to-one relationship to a GroupItem :

Code:
...
<many-to-one name="groupItem" column="IC_GROUP_ITEM_UID" class="GroupItem" not-null="true"/>
...


Item mapping snippets:

Code:
<hibernate-mapping package="com.tirzmax.data.inventory">
   <class name="Item" table="IC_ITEM" lazy="true">
      <id name="uid" column="IC_ITEM_UID" type="string" length="32">
         <generator class="uuid.hex"/>
      </id>

      ...

      <!-- GROUPITEM SUBCLASS -->
      <joined-subclass name="GroupItem" table="IC_GROUP_ITEM" lazy="true">
         <key column="IC_ITEM_UID"/>

         <property name="collapsed" column="COLLAPSED" type="boolean" not-null="true"/>

         <set name="includes" lazy="true" inverse="true">
            <key column="IC_ITEM_UID"/>
            <one-to-many class="GroupItemInclude"/>
         </set>

         <set name="attachments" lazy="true" inverse="true">
            <key column="IC_ITEM_UID"/>
            <one-to-many class="GroupItemAttachment"/>
         </set>

      </joined-subclass>
</class>
</hibernate-mapping>


Notice the key length of 32 for the Item class heirarchy. The DDL generated for the GroupItemInclude class is fine. By fine I mean the IC_GROUP_ITEM_UID column has the appropriate length of 32. However, the DDL for the GroupItemAttachment class has a length of 255 for the IC_GROUP_ITEM_UID column. The order that the tables are output is GroupItemAttachment, GroupItem, GroupItemInclude.

For some reason SchemaExport is not recognizing the size restriction on that column in this instance. I have other classes mapped, but their FKs all come out just fine. For examples, there is a Company class with the same length restriction on the PK that just about every class references and they all have a length of 32. The Company DDL is way down in the output order( well past FKs that are pointing to it ).

Any suggestions??


Top
 Profile  
 
 Post subject: wrong length for primary keys
PostPosted: Thu Mar 18, 2004 5:49 am 
Newbie

Joined: Thu Nov 06, 2003 8:28 am
Posts: 8
I have the same problem: somethimes the keys in joined subclasses and in many-to-many mapping tables have the correct length, and somethimes they have the default length of 255. In the case of the mapping tables MySQL will complain about too long primary keys (except when using innoDB tables).

mapping (one file per class):

<class name="doks.record.Record">
<id name="id" column="id" type="string" length="36" >
...
</class>

<joined-subclass name="structures.TestExt" extends="doks.record.Record" table="S_TestExt">
<key column="id" />
...
</joined-subclass>

<joined-subclass name="structures.Discussion" extends="doks.record.Record" table="S_Discussion">
<key column="id" />
<set name="recordreflist"
table="L_TestExt_recordreflist"
lazy="true" >
<key> <column name="from_id" /> </key>
<many-to-many
class="doks.record.Record"
column="to_id"
outer-join="auto"
/>
</set>
...
</joined-subclass>

tables:

create table S_TestExt (
id VARCHAR(255) not null,
...
primary key (id)
);
create table S_Discussion (
id VARCHAR(36) not null,
...
primary key (id)
);
create table L_TestExt_recordreflist (
from_id VARCHAR(255) not null,
to_id VARCHAR(36) not null,
primary key (from_id, to_id)
);
create table L_Keyword__records (
from_id VARCHAR(255) not null,
to_id VARCHAR(255) not null,
primary key (from_id, to_id)
);
create table Record (
id VARCHAR(36) not null,
...
primary key (id)
);


Top
 Profile  
 
 Post subject: SchemaExport column length problem (bug)
PostPosted: Mon Mar 29, 2004 6:12 am 
Newbie

Joined: Thu Nov 06, 2003 8:28 am
Posts: 8
Hi there,

I investigated the mentioned problems and found two workarounds:

1)I noticed that I have foreign key length problems with all the tables involving bidirectional many-to-many collections. Because I'm using one configuration file per class, I'm able to change the order in which the configuration files are loaded. When I make sure that the configuration files that declare the collection as inverse=false are loaded before the class with inverse=true, the length of the foreing keys are correct.
I guess this workaround doesn't work when there are multiple inverse fields that connect the classes in a circle, but I didn't test it.

2)The column length of the primary key of a joined subclass is set the same as of the superclass, but if this superclass is also a joined subclass, its primary key length may not have been set already. This also means that all relationships also use the wrong length for foregn keys.
This can be worked around by changing secondPassCompile() in Configuration.java (I hope someone who knows this code better then me can clean it up):
Code:
   // This method may be called many times!!
   private void secondPassCompile() throws MappingException {

      //first process the foreign key constraints
      log.info("processing foreign key constraints");
      //make sure that classes are handled before their subclasses
      Iterator iter = getClassMappings();
      while ( iter.hasNext() ) {
         PersistentClass classMapping = (PersistentClass) iter.next();
         if (classMapping.getSuperclass()==null)
         processForeignKeyConstraints(classMapping);
      }
      //process the foreign keys a second time to include collection tables
      iter= getTableMappings();
      while ( iter.hasNext() ) {
         processForeignKeyConstraints((Table)iter.next());
      }

      log.info("processing one-to-many association mappings");

      iter = secondPasses.iterator();
      while ( iter.hasNext() ) {
         Binder.SecondPass sp = (Binder.SecondPass) iter.next();
         sp.doSecondPass(classes);
         iter.remove();
      }
      
      log.info("processing one-to-one association property references");
      
      iter = propertyReferences.iterator();
      while ( iter.hasNext() ) {
         Mappings.UniquePropertyReference upr = (Mappings.UniquePropertyReference) iter.next();
         PersistentClass clazz = getClassMapping(upr.referencedClass);
         if (clazz==null) throw new MappingException( "property-ref to unmapped class: " + upr.referencedClass.getName() );
         boolean found = false;
         Iterator propIter = clazz.getPropertyIterator();
         while ( propIter.hasNext() ) {
            Property prop = (Property) propIter.next();
            if ( upr.propertyName.equals( prop.getName() ) ) {
               ( (SimpleValue) prop.getValue() ).setUnique(true);
               found = true;
               break;
            }
         }
         if (!found) throw new MappingException(
            "property-ref not found: " + upr.propertyName +
            " in class: " + upr.referencedClass.getName()
         );
      }
      
      //TODO: Somehow add the newly created foreign keys to the internal collection

   }

   //introduced two new methods
   private void processForeignKeyConstraints(PersistentClass classMapping) throws MappingException {
      processForeignKeyConstraints(classMapping.getTable());
      Iterator subClassIter= classMapping.getDirectSubclasses();
      while(subClassIter.hasNext()){
         processForeignKeyConstraints((PersistentClass) subClassIter.next());
      }
   }

   private void processForeignKeyConstraints(Table table) throws MappingException {
      System.out.println("processForeignKeyConstraints:"+ table.getName());
      Iterator subIter = table.getForeignKeyIterator();
      while ( subIter.hasNext() ) {

         ForeignKey fk = (ForeignKey) subIter.next();
         //skip the test because each key will be processed two times
         //if ( fk.getReferencedTable() == null ) {
            if ( log.isDebugEnabled() ) log.debug(
               "resolving reference to class: " + fk.getReferencedClass().getName()
            );
            PersistentClass referencedClass = (PersistentClass) classes.get( fk.getReferencedClass() );
            if (referencedClass == null) throw new MappingException(
               "An association from the table " +
               fk.getTable().getName() +
               " refers to an unmapped class: " +
               fk.getReferencedClass().getName()
            );
            fk.setReferencedTable( referencedClass.getTable() );
         //}
      }
   }


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