I ran into an issue with mapping an @Embeddable inside of an collection of @Embeddable components:
Code:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.hibernate.persister.collection.AbstractCollectionPersister.initCollectionPropertyMap(AbstractCollectionPersister.java:1736)
at org.hibernate.persister.collection.AbstractCollectionPersister.initCollectionPropertyMap(AbstractCollectionPersister.java:1712)
at org.hibernate.persister.collection.AbstractCollectionPersister.<init>(AbstractCollectionPersister.java:600)
at org.hibernate.persister.collection.BasicCollectionPersister.<init>(BasicCollectionPersister.java:74)
at org.hibernate.persister.PersisterFactory.createCollectionPersister(PersisterFactory.java:104)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:318)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at com.rtrms.hibernate.View.main(View.java:46)
Here's a simplified version of the object model that can be run to reproduce:
Code:
package com.rtrms.hibernate;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import org.apache.log4j.BasicConfigurator;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.HSQLDialect;
import org.hsqldb.jdbcDriver;
@Entity
@Table(name = "VIEW")
public class View {
@Id
@Column(name = "ID")
protected Long id;
@JoinTable(name = "VIEW_COLUMN", joinColumns = { @JoinColumn(name = "VIEW_ID") })
@ElementCollection
@IndexColumn(name = "COLUMN_INDEX")
@Cascade(CascadeType.ALL)
private List<ViewColumn> columns;
public static void main(String[] args) {
BasicConfigurator.configure();
Configuration config = new AnnotationConfiguration().addAnnotatedClass(View.class).addAnnotatedClass(FilterImpl.class);
config.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
config.setProperty(Environment.DRIVER, jdbcDriver.class.getName());
config.setProperty(Environment.URL, "jdbc:hsqldb:mem:testDB;shutdown=true");
config.setProperty(Environment.USER, "SA");
config.setProperty(Environment.PASS, "");
config.buildSessionFactory();
}
}
Code:
package com.rtrms.hibernate;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
@Embeddable
public class ViewColumn {
@Column(name = "NAME")
private String name;
@Embedded
private ColumnProperties properties = new ColumnProperties();
}
Code:
package com.rtrms.hibernate;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.Target;
import org.hibernate.annotations.Type;
@Embeddable
public class ColumnProperties {
@Column(name = "CONFIGURATION")
@Type(type = "text")
private String configuration;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "FILTER_ID")
@Target(FilterImpl.class)
private Filter filter;
}
Code:
package com.rtrms.hibernate;
public interface Filter {
public void accept(ViewColumn column);
}
Code:
package com.rtrms.hibernate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "FILTER")
public class FilterImpl implements Filter {
@Id
@Column(name = "ID")
protected Long id;
@Override
public void accept(ViewColumn column) {
}
}
It seems to be failing while setting up the ViewColumn collection persister, trying to map the Embeddable properties object to a column. Is there a restriction with mapping nested Embeddables in this way or is the mapping incorrect? This is on Hibernate 3.5.5.