问题
I am following Hibernate Documentation and trying to implement the example given for section 9.4. Components as composite identifiers
but facing issues on how to implement it.
Here is what I have done:
My entity classes:
Order.java
public class Order {
private int id;
private Set<OrderLine> lines = new HashSet<OrderLine>();
// Setters & Getters
}
OrderLine.java
public class OrderLine {
private OrderLineId id;
private String name;
private Order order;
// Setters & Getters
}
OrderLineId.java
public class OrderLineId implements Serializable{
private int lineId;
private int orderId;
private int customerId;
// Setters & Getters
}
My mapping file which is having issues:
<hibernate-mapping>
<class name="Order" table="TEST_Order">
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="lines" cascade="all">
<key column="orderId"/>
<one-to-many class="OrderLine"/>
</set>
</class>
<class name="OrderLine" table="TEST_OrderLine">
<composite-id name="id" class="OrderLineId">
<key-property name="lineId"/>
<key-property name="orderId"/>
<key-property name="customerId"/>
</composite-id>
<property name="name"/>
<many-to-one name="order" class="Order"
insert="false" update="false">
<column name="orderId"/>
<column name="customerId"/>
</many-to-one>
</class>
</hibernate-mapping>
When I am trying to create a session factory which parses this mapping file, I am getting an exception saying:
Caused by: org.hibernate.MappingException: Foreign key (FK_89b4nqt5l2n6tfd1d5tq0ill0:TEST_OrderLine [orderId,customerId])) must have same number of columns as the referenced primary key (TEST_Order [id])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:110)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:93)
at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1816)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1739)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
Can someone please help me how to implement the example given in the documentation.
回答1:
The OrderLine needs to refernece the Order PK, which is not a composite key.
It means the many-to-one must be:
<many-to-one name="order" class="Order"
insert="false" update="false">
<column name="orderId"/>
</many-to-one>
The orderId is the FK to Order.id.
Then the one-to-many side will become:
<set name="lines" cascade="all">
<key>
<column name="orderId"/>
</key>
<one-to-many class="OrderLine"/>
</set>
So even if the OrderLine has a composite-key, the reference is made after Order.id, which is a simple key.
If you want to map other association to OrderLine, like OrderLineProduct then you'll need to use the composite-key to map the association between the parent (OrderLine) and the child (OrderLineProduct), so that OrderLineProduct has a composite-foreign-key back to OrderLine.
回答2:
In both the table hbm mapping you should have same no. of column ,what you are using to make composite.You need to add these 3 column in TEST_Oder.
Example to follow :
<many-to-one name="orderLine" class="OrderLine">
<column name="lineId"/>
<column name="orderId"/>
<column name="customerId"/>
</many-to-one>
Refer same URL
来源:https://stackoverflow.com/questions/25664452/components-as-composite-identifiers-in-hibernate