I am using Hibernate Annotations 3.2.0.GA. I have just upgraded from
Hibernate
Annotations Hibernate Annotations 3.0.beta2.
In the earlier release, I created a class that had a property for an
array of strings.
This array is being populated from a HTML form. This is running in a
servlet and I
use hbm2ddl to create the tables. The class looks like this.
@Entity
public class ComplexDataPersistent {
...
private String[] extra;
@OneToMany
@IndexColumn(name="extra_pos", base=0)
public String[] getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
...
}
In the earlier release, a table was created for ComplexDataPersistent
and a related table was created
for String array, named ComplexDataPersistent_extra. All was good.
In the new release, when I run the code, I get this error.
ERROR 2006-12-11 09:25:52,526 - Error in bean; could not initialize Hibernate.
org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped
class: ch6.complexPersistent.ComplexDataPersistent.extra[java.lang.String]
at
org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:979)
at
org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:530)
at org.hibernate.cfg.annotations.ListBinder$1.secondPass(ListBinder.java:65)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1127)
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 utilities.HibernateUtil.initSessionFactory(HibernateUtil.java:45)
I looked into the code source for both versions and found the following
difference
in CollectionBinder for the new release.
//check for user error
if ( ! isCollectionOfEntities ) {
if ( property.isAnnotationPresent( ManyToMany.class ) || property.isAnnotationPresent(
OneToMany.class ) ) {
String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
throw new AnnotationException(
"Use of @OneToMany or @ManyToMany targeting an unmapped class: " + path
+ "[" + collType + "]"
);
}
else {
JoinTable joinTableAnn = property.getAnnotation( JoinTable.class );
if ( joinTableAnn != null && joinTableAnn.inverseJoinColumns().length >
0 ) {
String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
throw new AnnotationException(
"Use of @JoinTable.inverseJoinColumns targeting an unmapped class: "
+ path + "[" + collType + "]"
);
}
}
}
This code is executed when the servlet starts and tries to drop the
previous tables.
It is unable to find the table for the string array, so an exception is
thrown. The exception
is preventing the tables from being created the first time.
I modified the code so that an error is written to the log instead of
having an
exception thrown and my code now works in the new version.
if ( property.isAnnotationPresent( ManyToMany.class ) || property.isAnnotationPresent(
OneToMany.class ) ) {
String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
//throw new AnnotationException(
log.error("Use of @OneToMany or @ManyToMany targeting an unmapped class:
" + path + "[" + collType + "]");
//);
}
Now the table for the string array is created as it was before and the
application is running as it did before.
Show replies by date