问题
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;
}
}
回答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
回答2:
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>
回答3:
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>
来源:https://stackoverflow.com/questions/17291729/why-am-i-getting-mapping-exception