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