The blog records how to map two entities by the composite keys by using hibernate. Let's say we have 2 entities PrizeItem
and PrizeWinnerInfo
. We want to map them as OneToOne relation.
The PrizeWinnerInfo
(pzwininfo_pzitem_pz_id, pzwininfo_pzitem_id) refer to PrizeItem
(pzitem_pz_id, pzitem_id) with the composite foreign key.
Step 0.
Database schema of PrizeItem
, table name: ix_prize_item
+----------------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------------------+--------------+------+-----+---------+-------+ | pzitem_pz_id | bigint(20) | NO | PRI | NULL | | | pzitem_id | int(11) | NO | PRI | NULL | | | pzitem_expiration | datetime | YES | | NULL | | | pzitem_won | tinyint(1) | NO | | 0 | | | pzitem_won_time | datetime | YES | | NULL | | | pzitem_winner_info_applied | tinyint(1) | NO | | 0 | | | pzitem_pzcha_id | int(11) | YES | MUL | NULL | | | pzitem_serial | varchar(255) | YES | | NULL | | +----------------------------+--------------+------+-----+---------+-------+
Database schema of PrizeWinnerInfo
, table name: ix_prize_winner_info
+------------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+--------------+------+-----+---------+-------+ | pzwininfo_pzcha_id | int(11) | NO | MUL | 0 | | | pzwininfo_pzitem_pz_id | bigint(20) | NO | PRI | 0 | | | pzwininfo_pzitem_id | int(11) | NO | PRI | 0 | | | pzwininfo_name | varchar(255) | NO | | NULL | | | pzwininfo_email | varchar(128) | NO | | NULL | | | pzwininfo_phone | varchar(32) | YES | | NULL | | | pzwininfo_detail | longtext | YES | | NULL | | +------------------------+--------------+------+-----+---------+-------+
Step 1.
Tip: Use @Embeddable
to define the composite key
The composite primary key PrizeItemPK
of PrizeItem
@Embeddable public class PrizeItemPK implements Serializable { private final static long serialVersionUID = 1L; @Column(name="pzitem_pz_id") private Long prizeId; @Column(name="pzitem_id") private Integer prizeItemId; public PrizeItemPK() {} public PrizeItemPK(Long prizeId, Integer prizeItemId) { super(); this.prizeId = prizeId; this.prizeItemId = prizeItemId; } @JsonGetter("prize_id") public Long getPrizeId() { return prizeId; } public void setPrizeId(Long prizeId) { this.prizeId = prizeId; } @JsonGetter("prize_item_id") public Integer getPrizeItemId() { return prizeItemId; } public void setPrizeItemId(Integer prizeItemId) { this.prizeItemId = prizeItemId; } }
The composite primary key PrizeWinnerInfoPK
of PrizeWinnerInfo
@Embeddable public class PrizeWinnerInfoPK implements Serializable { private final static long serialVersionUID = 1L; @Column(name="pzwininfo_pzitem_pz_id") private Long prizeId; @Column(name="pzwininfo_pzitem_id") private Integer prizeItemId; public PrizeWinnerInfoPK() {} public PrizeWinnerInfoPK(Long prizeId, Integer prizeItemId) { super(); this.prizeId = prizeId; this.prizeItemId = prizeItemId; } @JsonGetter("prize_id") public Long getPrizeId() { return prizeId; } public void setPrizeId(Long prizeId) { this.prizeId = prizeId; } @JsonGetter("prize_item_id") public Integer getPrizeItemId() { return prizeItemId; } public void setPrizeItemId(Integer prizeItemId) { this.prizeItemId = prizeItemId; } }
Step2.
Tip1: Use @OneToMany
mapping, not @OneToOne
Tip2: Use @JsonManagedReference
and @JsonBackReference
to avoid cycling json serialization
ORM entity of PrizeItem
@Entity @Table(name="ix_prize_item") @JsonAutoDetect(getterVisibility=JsonAutoDetect.Visibility.NONE) public class PrizeItem { @EmbeddedId private PrizeItemPK pk; ... @OneToMany(mappedBy="prizeItem", fetch=FetchType.EAGER) @JsonBackReference private ListwinnerInfo; }
ORM entity of PrizeWinnerInfo
@Entity @Table(name="ix_prize_winner_info") @JsonAutoDetect(getterVisibility=JsonAutoDetect.Visibility.NONE) public class PrizeWinnerInfo extends AbstractExtensibleJsonAliasBean { @EmbeddedId private PrizeWinnerInfoPK PK; ... @ManyToOne(fetch=FetchType.EAGER) @JoinColumns ({ @JoinColumn(name="pzwininfo_pzitem_pz_id", referencedColumnName = "pzitem_pz_id", insertable = false, updatable = false), @JoinColumn(name="pzwininfo_pzitem_id", referencedColumnName = "pzitem_id", insertable = false, updatable = false) }) @JsonManagedReference private PrizeItem prizeItem; }
2014/01/16 Note:
I found the use of @JsonBackReference
will make the serialization fail on that field. So, I took the below solution (http://stackoverflow.com/a/10111411/474002)
No comments:
Post a Comment