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?