Hello,
I am trying to define a many to many relationship and am running into some problems.
First I get the exception below. But I am also interested in finding out that the recommended approach is for retrieving a list of addresses that are associated for -PARENT_ID AND PARENT_TYPE. this is half the key. Will the association enable this or do I need to write a query for it.
I have an ADDRESS table that is being shared across a few entities such as User, Org, etc. To enable this, I have an ADDRESS_LINK table. The table structure is shown below:
Code:
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)
);
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)
);
Mapping documents:the mapping for these two tables.
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>
<many-to-one name="addresses"
entity-name="org.openiam.idm.srvc.continfo.dto.Address"
column="ADDRESS_ID"
insert="false"
update="false"
not-null="true" />
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<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():JUnit Code:
Code:
public void testAddAddress() {
Set addressSet = new HashSet();
addressSet.add(adr1);
AddressLink link = new AddressLink(adr1.getParentId(),adr1.getParentType(),adr1.getAddressId());
link.setAddresses(addressSet);
linkDAO.add(link);
}
AddressLinkDAOImpl
Code:
public void add(AddressLink transientInstance) {
log.debug("persisting AddressLink instance");
try {
sessionFactory.getCurrentSession().persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
AddressLink
Code:
public class AddressLink implements java.io.Serializable {
// Fields
private AddressLinkId id;
private Set addresses = new HashSet(0);;
/** default constructor */
public AddressLink() {
}
/** full constructor */
public AddressLink(AddressLinkId id) {
this.id = id;
}
public AddressLink(String parentId, String parentType, String addressId) {
id = new AddressLinkId(parentId, parentType, addressId);
}
// Property accessors
public AddressLinkId getId() {
return this.id;
}
public void setId(AddressLinkId id) {
this.id = id;
}
public Set getAddresses() {
return addresses;
}
public void setAddresses(Set address) {
this.addresses = address;
}
}
Address
Code:
public class Address implements java.io.Serializable {
// Fields
private String addressId;
private String country;
private String address1;
private String address2;
private String city;
private String state;
private String postalCd;
private Integer isDefault;
private String description;
private String parentId;
private String parentType;
// Constructors
/** default constructor */
public Address() {
}
/** minimal constructor */
public Address(String addressId) {
this.addressId = addressId;
}
/** full constructor */
public Address(String addressId, String country, String address1,
String address2, String city, String state, String postalCd,
Integer isDefault, String description) {
this.addressId = addressId;
this.country = country;
this.address1 = address1;
this.address2 = address2;
this.city = city;
this.state = state;
this.postalCd = postalCd;
this.isDefault = isDefault;
this.description = description;
}
// Property accessors
public String getAddressId() {
return this.addressId;
}
public void setAddressId(String addressId) {
this.addressId = addressId;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public String getAddress1() {
return this.address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return this.address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCd() {
return this.postalCd;
}
public void setPostalCd(String postalCd) {
this.postalCd = postalCd;
}
public Integer getIsDefault() {
return this.isDefault;
}
public void setIsDefault(Integer isDefault) {
this.isDefault = isDefault;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* Returns the Id of the parent that owns this address. The parent may be another entity like a
* USER, ORGANIZATION, etc
* @return
*/
public String getParentId() {
return parentId;
}
/**
* Associates the address with a parent entity, such as USER or ORGANIZATION that owns this address.
* @param parentId
*/
public void setParentId(String parentId) {
this.parentId = parentId;
}
/**
* Returns the type of the parent.
* @return
*/
public String getParentType() {
return parentType;
}
/**
* Sets the type of the parent. While the parent type can be anything you choose, a few
* constants are defined in the ContactConstants clss.
* @param parentType
*/
public void setParentType(String parentType) {
this.parentType = parentType;
}
}
Full stack trace of any exception that occurs:Code:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of org.openiam.idm.srvc.continfo.dto.Address.addressId
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3589)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3305)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:181)
at org.hibernate.engine.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:137)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:69)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:47)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
at org.openiam.idm.srvc.continfo.service.AddressLinkDAOImpl.add(AddressLinkDAOImpl.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:304)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy1.add(Unknown Source)
at org.openiam.idm.srvc.continfo.AddressLinkDAOTest.testAddAddress(AddressLinkDAOTest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
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)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
... 49 more
Name and version of the database you are using: MySQL 5