0

I am getting :

org.hibernate.MappingException: Foreign key (FKBB979BF4266AA123:address [a_id]))
must have same number of columns as the referenced 
primary key (address [p_id,a_id])

as I try to run the following (though incomplete) snippet :

    public static void main(String args[]) {
        Configuration config = new Configuration().configure();
        SessionFactory sessFact = config.buildSessionFactory();
        Session sess = sessFact.openSession();
        Transaction trans = sess.beginTransaction();    
    }

The hibernate mapping xml is shown below :

<class name="pojo.Person" table="person">
      <id column="p_id" name="personID">
          <generator class="increment" />
      </id>
      <property name="personName" column="p_name" />
      <set name="addressSet" table="address" cascade="all">
          <key column="p_id" />
          <many-to-many class="pojo.Address" column="a_id" />
      </set>
</class>

<class name="pojo.Address" table="address">
      <id column="a_id" name="addressID">
          <generator class="foreign" />
      </id>
      <property name="address" column="address" />
</class>

I am trying a many to many association between Person and Address class.

What is the reason for this exception ?

I have created two tables person and address using these sql commands :

CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id));
CREATE TABLE address(a_id INTEGER,address TEXT);

POJO

Person

public class Person {
    private int personID;
    private String personName;
    private Set addressSet;

    public int getPersonID() {
        return personID;
    }

    public void setPersonID(int personID) {
        this.personID = personID;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }

    public Set getAddressSet() {
        return addressSet;
    }

    public void setAddressSet(Set addressSet) {
        this.addressSet = addressSet;
    }

Address

public class Address {
    private int addressID;
    private String address;
    private Set personSet;

    public int getAddressID() {
        return addressID;
    }

    public void setAddressID(int addressID) {
        this.addressID = addressID;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Set getPersonSet() {
        return personSet;
    }

    public void setPersonSet(Set personSet) {
        this.personSet = personSet;
    }

}
2
  • It seems that your key consists of 2 combined fields and you're mapping to only 1 of those 2 fields. Commented Jun 25, 2013 at 7:50
  • @JorisRenting solution ? Commented Jun 25, 2013 at 7:54

3 Answers 3

1

For a ManyToMany Relationshhip you need a dedicated mapping table

6.2.4. Collections of values and many-to-many associations

i.e. You need something like a PersonAddress Table

CREATE TABLE personaddress (p_id integer, a_id integer)

Where p_id is a FK Reference to the Person Table and a_id a FK Reference to the Address Table

Sign up to request clarification or add additional context in comments.

Comments

1

You need to specify different table name for many-to-many association as it's handled by a separate table:

<class name="pojo.Person" table="person">
      <id column="p_id" name="personID">
          <generator class="increment" />
      </id>
      <property name="personName" column="p_name" />
      <set name="addressSet" table="person_address" cascade="all">
          <key column="p_id" />
          <many-to-many class="pojo.Address" column="a_id" />
      </set>
</class>

Note that <set> now references to person_addresses table. With default configuration, Hibernate is able to create it automatically.

There's another mistake that I see: ID generator for Address entity should not be foreign, it's usually used in 1-to-1 relationships (uses ID of another associated object). You can use the same 'increment' use used for Person entity:

<class name="Address" table="address">
    <id column="a_id" name="addressID">
        <generator class="increment" />
    </id>
    <property name="address" column="address" />
</class>

Comments

0

You need to create a reference table:

    CREATE TABLE PersonsAddresses (personId BIGINT, addressId BIGINT)

and change the mapping of the set to this:

    <set name="addressSet" table="PersonsAddresses" order-by="personId">
        <key column="personId" foreign-key="p_id"/>
        <many-to-many column="addressId" node="a_id" class="pojo.Address" />
    </set>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.