I use the following code to generate DDL:
Code:
package ro.dbexport;
import java.io.File;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.FileSystemResource;
public class HibernateSchemaExporter {
   
   public static void main(String[] args) throws Exception {
      export(true,"org.hibernate.dialect.PostgreSQLDialect");
   }
   
   public static void export(boolean createOnly, String dialect) throws Exception {
      GenericApplicationContext context = new GenericApplicationContext();
      XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context);
      xmlReader.loadBeanDefinitions(new FileSystemResource("WebContent/WEB-INF/ro-data.xml"), 
                                  new FileSystemResource("WebContent/WEB-INF/ro-security.xml"), 
                                  new FileSystemResource("WebContent/WEB-INF/ro-service.xml"), 
                                  new FileSystemResource("WebContent/WEB-INF/ro-servlet.xml"));
      context.refresh();
      
      export(context, createOnly, dialect);
   }
   
   public static void export(GenericApplicationContext context,boolean createOnly, String dialect) throws Exception {
      
      Configuration configuration = new Configuration();
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/persistence/UserTypes.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Activity.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/ActivityForecast.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/ActivityUnit.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Address.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/AssignedActivity.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/City.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Country.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Customer.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Expense.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Forecast.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Message.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Project.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/State.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/Subsystem.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/model/User.hbm.xml"));
      configuration.addFile(new File("/home/henry/workspace/JPAHibernate/RemOpt/src/ro/persistence/UserTypes.hbm.xml"));
      
      configuration.setProperty("hibernate.dialect", dialect);
      SchemaExport export = new SchemaExport(configuration);
      export.setOutputFile("ro-sql.ddl");
      export.setDelimiter(";");      
      export.execute(true, false, false, createOnly);
   }   
}
When I get the sql.ddl file I get duplicated columns and constraints this is a persistence class:
Code:
package ro.model;
import java.io.Serializable;
import java.util.Date;
@SuppressWarnings("serial")
public class ActivityForecast implements Serializable, Comparable<Object> {
   
   public static class Id implements Serializable {
      private Long forecastId;
      private Long activityId;
      
      public Id() {
         super();
      }
      
      public Id(Long forecastId, Long activityId) {
         super();
         this.forecastId = forecastId;
         this.activityId = activityId;
      }
                //getters and setters omitted.
      @Override
      public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result
               + ((activityId == null) ? 0 : activityId.hashCode());
         result = prime * result
               + ((forecastId == null) ? 0 : forecastId.hashCode());
         return result;
      }
      @Override
      public boolean equals(Object obj) {
         if (this == obj) {
            return true;
         }
         if (obj == null) {
            return false;
         }
         if (!(obj instanceof Id)) {
            return false;
         }
         Id other = (Id) obj;
         if (activityId == null) {
            if (other.activityId != null) {
               return false;
            }
         } else if (!activityId.equals(other.activityId)) {
            return false;
         }
         if (forecastId == null) {
            if (other.forecastId != null) {
               return false;
            }
         } else if (!forecastId.equals(other.forecastId)) {
            return false;
         }
         return true;
      }
      @Override
      public String toString() {
         return "Id [activityId=" + activityId + ", forecastId="
               + forecastId + "]";
      }
      
   }
   
   private Id id;
   
   private int version = 0;
   private Date created = new Date();
   
   private Activity activity;
   private Forecast forecast;
   private Integer forecastedQuantity;
   
   public ActivityForecast() {
      super();
   }
   
   public ActivityForecast(Activity activity, Forecast forecast,
         Integer forecastedQuantity) {
      super();
      this.activity = activity;
      this.forecast = forecast;
      this.forecastedQuantity = forecastedQuantity;
   }
        //getters and setters omitted.
   public int compareTo(Object object) {
      
      if (object instanceof ActivityForecast)
         return getCreated().compareTo(( (ActivityForecast) object).getCreated() );
      
      return 0;
   }
   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result
            + ((activity == null) ? 0 : activity.hashCode());
      result = prime * result
            + ((forecast == null) ? 0 : forecast.hashCode());
      result = prime
            * result
            + ((forecastedQuantity == null) ? 0 : forecastedQuantity
                  .hashCode());
      return result;
   }
   @Override
   public boolean equals(Object obj) {
      if (this == obj) {
         return true;
      }
      if (obj == null) {
         return false;
      }
      if (!(obj instanceof ActivityForecast)) {
         return false;
      }
      ActivityForecast other = (ActivityForecast) obj;
      if (activity == null) {
         if (other.activity != null) {
            return false;
         }
      } else if (!activity.equals(other.activity)) {
         return false;
      }
      if (forecast == null) {
         if (other.forecast != null) {
            return false;
         }
      } else if (!forecast.equals(other.forecast)) {
         return false;
      }
      if (forecastedQuantity == null) {
         if (other.forecastedQuantity != null) {
            return false;
         }
      } else if (!forecastedQuantity.equals(other.forecastedQuantity)) {
         return false;
      }
      return true;
   }
   @Override
   public String toString() {
      return "ActivityForecast [activity=" + activity + ", forecast="
            + forecast + ", forecastedQuantity=" + forecastedQuantity + "]";
   }
}
This is the ActivityForecast.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="ro.model" default-access="property">
<class name="ActivityForecast" table="ACTIVITY_FORECAST" batch-size="10" >
    <composite-id name="id" class="ActivityForecast$Id" >
        <key-property name="forecastId" column="ACTIVITY_FORECAST_FORECAST_ID" type="long" />
        <key-property name="activityId" column="ACTIVITY_FORECAST_ACTIVITY_ID" type="long" />
    </composite-id>
   <version name="version" column="ACTIVITY_FORECAST_OBJECT_VERSION" />
   <property name="created" column="ACTIVITY_FORECAST_CREATED" type="timestamp" update="false" not-null="true"/>
   
   <property name="forecastedQuantity" type="integer" column="ACTIVITY_FORECAST_FORECASTED_QUANTITY" length="256" not-null="true" />
   <many-to-one name="forecast" class="Forecast" column="ACTIVITY_FORECAST_FORECAST_ID" foreign-key="FK_ACTIVITY_FORECAST_FORECAST" not-null="true" insert="false" update="false" />
   <many-to-one name="activity" class="Activity" column="ACTIVITY_FORECAST_ACTIVITY_ID" foreign-key="FK_ACTIVITY_FORECAST_ACTIVITY" not-null="true" insert="false" update="false" />   
</class>
   
</hibernate-mapping>
This is the generated schema: (Note the repeated columns and constraints)
Code:
create table ACTIVITY_FORECAST (ACTIVITY_FORECAST_FORECAST_ID int8 not null, ACTIVITY_FORECAST_ACTIVITY_ID int8 not null, ACTIVITY_FORECAST_OBJECT_VERSION int4 not null, ACTIVITY_FORECAST_CREATED timestamp not null, ACTIVITY_FORECAST_FORECASTED_QUANTITY int4 not null, ACTIVITY_ID int8, FORECAST_ID int8 not null, primary key (ACTIVITY_FORECAST_FORECAST_ID, ACTIVITY_FORECAST_ACTIVITY_ID));
alter table ACTIVITY_FORECAST add constraint FK_FORECAST_ACTIVITY_FORECAST foreign key (FORECAST_ID) references FORECAST;
alter table ACTIVITY_FORECAST add constraint FK_ACTIVITY_FORECAST foreign key (ACTIVITY_ID) references ACTIVITY;
alter table ACTIVITY_FORECAST add constraint FK_ACTIVITY_FORECAST_FORECAST foreign key (ACTIVITY_FORECAST_FORECAST_ID) references FORECAST;
alter table ACTIVITY_FORECAST add constraint FK_ACTIVITY_FORECAST_ACTIVITY foreign key (ACTIVITY_FORECAST_ACTIVITY_ID) references ACTIVITY;
How can I avoid hbm2ddl from generating duplicated columns and constraints? Is this a Hibernate bug?