Hello,
I am trying to implement a many to many relationship and getting the exception below. I was hoping to get some suggestions on how to get this working.
- Should I be creating a mapping between the two tables below or should I be using the data access classes to do most of handling.
- If I should be using a mapping, how should I set up the maps when I have a composite key involved?
schema
Code:
CREATE TABLE ADDRESS_LINK(
ADDRESS_ID varchar(20) NOT NULL,
PARENT_ID varchar(20) NOT NULL,
PARENT_TYPE varchar(30) NOT NULL,
PRIMARY KEY (PARENT_ID, PARENT_TYPE, ADDRESS_ID)
);
CREATE TABLE ADDRESS (
ADDRESS_ID varchar(20) NOT NULL,
COUNTRY varchar(30) NULL,
ADDRESS1 varchar(45) NULL,
ADDRESS2 varchar(45) NULL,
CITY varchar(30) NULL,
STATE varchar(15) NULL,
POSTAL_CD varchar(10) NULL,
IS_DEFAULT int NULL DEFAULT 0,
DESCRIPTION varchar(25) NULL,
PRIMARY KEY (ADDRESS_ID)
);
Mapping documents:AddressLink map file:
Code:
<hibernate-mapping>
<class name="org.openiam.idm.srvc.continfo.dto.AddressLink" table="ADDRESS_LINK" >
<comment></comment>
<composite-id name="id" class="org.openiam.idm.srvc.continfo.dto.AddressLinkId">
<key-property name="parentId" type="string">
<column name="PARENT_ID" length="20" />
</key-property>
<key-property name="parentType" type="string">
<column name="PARENT_TYPE" length="30" />
</key-property>
<key-property name="addressId" type="string">
<column name="ADDRESS_ID" length="20" />
</key-property>
</composite-id>
<set name="addresses" cascade="all-delete-orphas">
<key>
<column name="addressId" />
</key>
<many-to-many class="org.openiam.idm.srvc.continfo.dto.Address" column="addressId" />
</set>
</class>
</hibernate-mapping>
Address map:
Code:
<class name="org.openiam.idm.srvc.continfo.dto.Address" table="ADDRESS">
<comment></comment>
<id name="addressId" type="string">
<column name="ADDRESS_ID" length="20" />
<generator class="assigned" />
</id>
<property name="country" type="string">
<column name="COUNTRY" length="30">
<comment></comment>
</column>
</property>
<property name="address1" type="string">
<column name="ADDRESS1" length="45">
<comment></comment>
</column>
</property>
<property name="address2" type="string">
<column name="ADDRESS2" length="45">
<comment></comment>
</column>
</property>
<property name="city" type="string">
<column name="CITY" length="30">
<comment></comment>
</column>
</property>
<property name="state" type="string">
<column name="STATE" length="15">
<comment></comment>
</column>
</property>
<property name="postalCd" type="string">
<column name="POSTAL_CD" length="10">
<comment></comment>
</column>
</property>
<property name="isDefault" type="java.lang.Integer">
<column name="IS_DEFAULT">
<comment></comment>
</column>
</property>
<property name="description" type="string">
<column name="DESCRIPTION" length="25">
<comment></comment>
</column>
</property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Unit test code:
Code:
public void testAddAddress() {
Set addressSet = new HashSet();
addressSet.add(adr1);
AddressLink link = new AddressLink(adr1.getParentId(),adr1.getParentType(),adr1.getAddressId());
linkDAO.add(link);
}
AddressLinkDAO code:
public void add(AddressLink transientInstance) {
log.debug("persisting AddressLink instance");
try {
sessionFactory.getCurrentSession().persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
re.printStackTrace();
log.error("persist failed", re);
throw re;
}
}
Full stack trace of any exception that occurs:Code:
nested exception is org.hibernate.MappingException: Foreign key (FK34207BA2E3118199:addresses [addressId])) must have same number of columns as the referenced primary key (ADDRESS_LINK [PARENT_ID,PARENT_TYPE,ADDRESS_ID])
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceDAO' defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK34207BA2E3118199:addresses [addressId])) must have same number of columns as the referenced primary key (ADDRESS_LINK [PARENT_ID,PARENT_TYPE,ADDRESS_ID])
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK34207BA2E3118199:addresses [addressId])) must have same number of columns as the referenced primary key (ADDRESS_LINK [PARENT_ID,PARENT_TYPE,ADDRESS_ID])
Caused by: org.hibernate.MappingException: Foreign key (FK34207BA2E3118199:addresses [addressId])) must have same number of columns as the referenced primary key (ADDRESS_LINK [PARENT_ID,PARENT_TYPE,ADDRESS_ID])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:90)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:73)
at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1263)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1170)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:805)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:745)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:428)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:261)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:109)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1100)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:862)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:424)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:261)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:109)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:389)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:120)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:720)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:387)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:91)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:75)
at org.openiam.idm.srvc.continfo.AddressLinkDAOTest.onSetUp(AddressLinkDAOTest.java:41)
at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:89)
at junit.framework.TestCase.runBare(TestCase.java:128)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:228)
at junit.framework.TestSuite.run(TestSuite.java:223)
at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
[/code]