I have a class, let's call it A, that contains a
List of class B. Each instance of B has a
List of class C. I'm trying to generate the DDL for this, so I've annotated the code and run it through
SchemaExport, which throws a
ConcurrentModificationException. My environment: Java 1.5, Oracle 10, Hibernate 3.2.1ga.
The problem seems to be caused by having an entity (A) containing an embedded collection (of B), each element of which contains a collection (of C). SchemaExport generates correct DDL when the annotations are modified to make B and/or C an entity, but not when they are both components. I realise this is considered something of an exotic case, but I'd like to know why the DDL doesn't generate.
Here's the Java code:
Code:
@Entity
@Table(name="A")
public class A {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="aSequence")
@SequenceGenerator(name="aSequence", sequenceName="seq_A")
private int id;
@CollectionOfElements
@IndexColumn(name="indx")
private List<B> listOfB;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<B> getListOfB() {
return listOfB;
}
public void setListOfB(List<B> listOfB) {
this.listOfB = listOfB;
}
}
@Embeddable
public class B {
@CollectionOfElements
@IndexColumn(name="ndx")
private List<C> listOfC;
public List<C> getListOfC() {
return listOfC;
}
public void setListOfC(List<C> listOfC) {
this.listOfC = listOfC;
}
}
@Embeddable
public class C {
@Column(length=500)
private String comment;
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
The code to call SchemaExport:
Code:
public class DBGen {
/**
* Simple program to generate the database schema from the
* Hibernate annotations
*/
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("usage: DBGen <sqlFile>");
System.exit(-1);
}
try {
Configuration cfg =
new AnnotationConfiguration().configure("WEB-INF/hibernate.cfg.xml");
new SchemaExport(cfg).
setOutputFile(args[0]).
setFormat(true).
setDelimiter(";").
create(true, false);
System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
The Hibernate configuration file:
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</property>
<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping class="A" />
</session-factory>
</hibernate-configuration>
And finally, the stack trace when I run this:
Code:
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1128)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:296)
at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:756)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:93)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:61)
at DBGen.main(DBGen.java:20)
Any insight or assistance would be greatly appreciated.