Question

here are the sql tables:
option primary key is name + value

CREATE TABLE `option` (
  id int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `value` varchar(45) NOT NULL,
  PRIMARY KEY (`name`, `value`),
  UNIQUE KEY `id_UNIQUE` (`id`)
)

product primary key is incremental id

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) 

a product has several options (referenced by unique key "id")

CREATE TABLE product_option (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_product` int(11) NOT NULL,
  `id_option` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id_product` (`id_product`),
  KEY `id_option` (`id_option`),
  CONSTRAINT `FK_product_option` FOREIGN KEY (`id_product`) REFERENCES `product` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_option_product` FOREIGN KEY (`id_option`) REFERENCES `option` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  )

On java side, i've mapped "option" this way

@Embeddable
public class OptionId implements Serializable{
    @Column(name="value")
    private String value;

    @Column(name="name")
    private String name;
}


@Entity @Table(name="option")
public class Option { 

    @Column(name="id", unique=true)
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @EmbeddedId
    private OptionId primaryKey;

    public OptionId getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(OptionId primaryKey) {
        this.primaryKey = primaryKey;
    }
}

and product this way

@Entity
@Table(name="product")
public class Product {

    @Id @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="name")
    private String name

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinTable(
            name="product_option",
            joinColumns = @JoinColumn( name="id_product"),
            inverseJoinColumns = @JoinColumn( name="id_option", referencedColumnName="id")
    )
    private Set<Option> options;
}

then at execution time i get this error

Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
    at org.hibernate.sql.SelectFragment.addColumns(SelectFragment.java:107)
    at org.hibernate.persister.collection.BasicCollectionPersister.manyToManySelectFragment(BasicCollectionPersister.java:308)
    at org.hibernate.persister.collection.BasicCollectionPersister.selectFragment(BasicCollectionPersister.java:294)
    at org.hibernate.loader.JoinWalker.selectString(JoinWalker.java:1070)
    at org.hibernate.loader.AbstractEntityJoinWalker.initStatementString(AbstractEntityJoinWalker.java:124)
    at org.hibernate.loader.AbstractEntityJoinWalker.initStatementString(AbstractEntityJoinWalker.java:109)
    at org.hibernate.loader.AbstractEntityJoinWalker.initAll(AbstractEntityJoinWalker.java:91)
    at org.hibernate.loader.AbstractEntityJoinWalker.initAll(AbstractEntityJoinWalker.java:78)
    at org.hibernate.loader.entity.CascadeEntityJoinWalker.<init>(CascadeEntityJoinWalker.java:52)
    at org.hibernate.loader.entity.CascadeEntityLoader.<init>(CascadeEntityLoader.java:47)
    at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:3254)
    at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:3191)
    at org.hibernate.persister.entity.SingleTableEntityPersister.postInstantiate(SingleTableEntityPersister.java:728)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    ... 60 more

if i remove "referencedColumnName", of course i get the error

A Foreign key refering Option from Product has the wrong number of column. should be 2

but i can't figure out how to fix this

No correct solution

OTHER TIPS

Based on your schemas, your entity annotations are slightly off. Where you specify 'product' and 'option' you should be using 'id_product' and 'id_option':

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinTable(
       name="product_option",
       joinColumns = @JoinColumn( name="id_product"),
       inverseJoinColumns = @JoinColumn( name="id_option", referencedColumnName="id")
)
private Set<Option> options;

As an aside, your life will be considerably easier, in the long run, if you switch the primary and unique keys on your option table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top