We have encountered an issue in Hibernate 3.0.5 where hbm2ddl generates incorrect DDL output. We do not have any particular urgency associated with this issue; we merely want to let the community know about it and seek input on whether we should submit it to the Hibernate JIRA as a bug. Details can be found below.
Given the following mapping file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sourcelabs.hibernatecollectiontestapp.model.ValuesAsSet" table="ValuesAsSet">
<id name="id" column="id" type="java.lang.Long">
<generator class="native">
<param name="sequence">idSeq</param>
</generator>
</id>
<property name="name" column="name" type="java.lang.String"/>
<set name="collection" table="ValueOppositeValuesAsSet" lazy="true" cascade="all-delete-orphan">
<key column="parentId"/>
<element type="java.lang.String" column="value"/>
</set>
</class>
</hibernate-mapping>
we get the following DDL output:
create table ValueOppositeValuesAsSet (parentId number(19,0) not null,
value varchar2(255));
create table ValuesAsSet (id number(19,0) not null, name varchar2(255),
primary key (id));
alter table ValueOppositeValuesAsSet add constraint FK9ABF10569903889F
foreign key (parentId) references ValuesAsSet;
There should be a primary key on parentID and value in the DDL output.
We have investigated the issue and discovered that fixing it would require substantial reworking of certain aspects of Hibernate. Changes would need to be made to Org.hibernate.cfg.Configuration. We recommend creating a new method that determines whether the table represents a set or not:
private boolean representsSet( Table t ) {
for(Iterator j = getCollectionMappings(); j.hasNext();){
Object value = j.next();
if( value instanceof org.hibernate.mapping.Set ){
org.hibernate.mapping.Set hset = ( org.hibernate.mapping.Set ) value;
if( t.equals( hset.getCollectionTable() )) {
return true;
}
}
}
return false;
}
This function would need to be called by #generateSchemaCreationScript, and the return value would need to be passed to Table#sqlCreateString. This would require changing the method's signature. Additionally, actual SQL generation would need to be performed inside the function. Such generation is likely to be DB-specific.
We were curious to see if anyone else has run into this, and whether we should submit this as a bug.
|