How do I specify the foreign key on a many-to-one relationship when is not a property on the object itself?
I'm trying to map a many-to-one relationship from MarketMenuBranch to Market. My classes look like:
public class Market implements Serializable {
private int id;
private String name;
private List<MarketMenuBranch> marketMenuBranches;
// accessors / mutators etc...
public class MarketMenuBranch implements Serializable {
private MarketMenuBranchId id;
private String name;
// accessors / mutators etc...
public class MarketMenuBranchId implements Serializable {
private int marketId;
private int sequence;
// accessors / mutators etc...
But I don't know what I can put for the property name (where I have ???? below). I really want to put id.marketId but that seems to be wrong.
<class name="MarketMenuBranch" table="MARKET_MENU_BRANCH">
<composite-id name="id" class="MarketMenuBranchId">
<key-property name="marketId"/>
<key-property name="sequence"/>
</composite-id>
<property name="name"/>
<many-to-one name="????????"/>
</class>
How can I do this?
EDIT: here is the Market mapping:
<class name="Market" table="MARKET">
<id name="id"/>
<property name="name"/>
<list name="marketMenuBranches" inverse="true" cascade="all-delete-orphan">
<key column="marketId"/>
<list-index column="sequence"/>
<one-to-many class="MarketMenuBranch"/>
</list>
</class>
and here are my tables:
mysql> describe MARKET;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
mysql> describe开发者_StackOverflow MARKET_MENU_BRANCH;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| marketId | int(11) | NO | PRI | 0 | |
| sequence | int(11) | NO | PRI | 0 | |
| name | varchar(100) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
Something goes wrong because more than one property share the same column. Your MarketMenuBranch should looks like (Notice insert="false", update="false")
<class name="MarketMenuBranch" table="MARKET_MENU_BRANCH">
<composite-id name="id" class="MarketMenuBranchId">
<!--Ops... A property whose mapped column is called marketId-->
<key-property name="marketId"/>
<key-property name="sequence"/>
</composite-id>
<property name="name"/>
<!--Ops... Other property whose mapped column is called marketId-->
<many-to-one name="market" column="marketId" insert="false" update="false"/>
</class>
Hibernate will ask to you: which property should i save/update ???
Because of that, you should define insert="false", update="false"
Are you a new Hibernate guy ???
Keep this in mind: Hibernate does not support automatic generation of composite primary key
So you should provide your composite primary key before saving
Perhaps you should map MarketMenuBranch as a list of composit elements:
<class name="Market" table="MARKET">
...
<list cascade="all-delete-orphan" name="marketMenuBranches" table="MARKET_MENU_BRANCH">
<key column="MARKET_ID"/>
<list-index column="SEQUENCE"/>
<composite-element class="MarketMenuBranch">
<property column="NAME" name="name"/>
</composite-element>
</list>
well I think your shouldn't name your data member 'id' in MarketMenuBranch since that is a bit confusing. I would recommend marketMenuBranch. Thats what it is right?
But, going off of what you have above you are just referencing the name of the class member you are referring to. So:
<many-to-one name="id" column="column_name" class="MarketMenuBranchId"/>
You are just pointing the the container object you made and are using as a class member. MarketMenuBranchId should be mapped as well and Hibernate will know how to get the id out of there and that is why you do not need to put id.marketId.
btw: I have no idea if the entire structure is correct (thats up to you) but this should answer your specific question. To me it seems your way of calling XXXId is a bit misleading, but you know your needs better than I.
edit: I also would point out that if you have any control over the DB at all I would recommend not using composite ids. It will make things a bit cumbersome in the future. And a system generated id follows the normalization rules a better.
精彩评论