java 如何使用注释在 Hibernate 中表示复合键?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7080611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Represent Composite keys in Hibernate using Annotations?
提问by Michael W
So I reverse engineered some tables from my db and when I try to save my object to the db I get the following error:
所以我从我的数据库中逆向工程了一些表,当我尝试将我的对象保存到数据库时,我收到以下错误:
Initial SessionFactory creation failed.org.hibernate.AnnotationException: A Foreign key refering com.mycode.Block from com.mycode.Account has the wrong number of column. should be 2 Exception in thread "main" java.lang.ExceptionInInitializerError
初始 SessionFactory 创建失败.org.hibernate.AnnotationException:从 com.mycode.Account 引用 com.mycode.Block 的外键具有错误的列数。应该是线程“main”中的 2 Exception java.lang.ExceptionInInitializerError
The Domain objects Are Block which contains a number of Account Objects:
域对象是块,其中包含许多帐户对象:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "Block")
public Set<EAccount> getAccounts() {
return this.Accounts;
}
Account has a Composite key of Id and Role. This has been setup in a seperate Class:
帐户具有 Id 和 Role 的复合键。这已在单独的类中设置:
@Embeddable
public class BlockAccountId implements java.io.Serializable {
private long blockOid;
private String accountRole;
public BlockAccountId() {
}
public BlockAccountId(long blockOid, String accountRole) {
this.blockOid = blockOid;
this.accountRole = accountRole;
}
@Column(name = "BLOCK_OID", nullable = false)
public long getBlockOid() {
return this.blockOid;
}
public void setBlockOid(long blockOid) {
this.blockOid = blockOid;
}
@Column(name = "ACCOUNT_ROLE", nullable = false, length = 10)
public String getAccountRole() {
return this.accountRole;
}
public void setAccountRole(String accountRole) {
this.accountRole = accountRole;
}
So I want to know. How can I Link the tables Block and account on blockOid but still ensure the account table has both blockOid and accountRole as a composite key.
所以我想知道。如何在 blockOid 上链接表 Block 和 account,但仍确保 account 表同时具有 blockOid 和 accountRole 作为复合键。
Any examples would be greatly appreciated!
任何例子将不胜感激!
N.B this is a Block (One) to Account (Many) relationship.
注意这是一个块(一个)到帐户(多个)的关系。
Thanks
谢谢
回答by Joel Hudon
The easiest is to place your association directly in the embedded id component.
最简单的方法是将您的关联直接放在嵌入的 id 组件中。
Hibernate reference documentation
- Section 5.1.2.1.1. id as a property using a component type ()
休眠参考文档
- 第 5.1.2.1.1 节。id 作为使用组件类型的属性 ()
Example (Only write the important getter() and setter())
示例(只写重要的 getter() 和 setter())
@Entity
public class Block {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="BLOCK_OID")
long blockOid;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.block", cascade=CascadeType.ALL)
Set<Account> accounts = new HashSet<Account>();
}
@Entity
public class Account {
@EmbeddedId BlockAccountId id;
public Account()
{
this.id = new BlockAccountId();
}
public void setBlock(Block pBlock) {
this.id.setBlock(pBlock);
}
public Block getBlock() {
return this.id.getBlock();
}
public String getAccountRole() {
return this.id.getAccountRole();
}
public void setAccountRole(String accountRole) {
this.id.setAccountRole(accountRole);
}
}
@Embeddable
public class BlockAccountId implements java.io.Serializable {
@ManyToOne(optional = false)
private Block block;
@Column(name = "ACCOUNT_ROLE", nullable = false, length = 10)
private String accountRole;
public BlockAccountId() {
}
//Implement equals and hashcode
}
The corresponding database table are :
对应的数据库表为:
CREATE TABLE block (
BLOCK_OID bigint(20) NOT NULL auto_increment,
PRIMARY KEY (`BLOCK_OID`)
)
CREATE TABLE account (
ACCOUNT_ROLE varchar(10) NOT NULL,
block_BLOCK_OID bigint(20) NOT NULL,
PRIMARY KEY (`ACCOUNT_ROLE`,`block_BLOCK_OID`),
KEY `FK_block_OID` (`block_BLOCK_OID`),
CONSTRAINT `FK_block_OID` FOREIGN KEY (`block_BLOCK_OID`) REFERENCES `block` (`BLOCK_OID`)
)
回答by Mohammad B Yaseen
based on hibernate documentation here's the link
基于休眠文档这里是链接
based on it you can do the following :
基于它,您可以执行以下操作:
@Entity public class Account {
@Entity 公共类帐户 {
@EmbeddedId BlockAccountId id;
@MapsId(value = "blockOid")
@ManyToOne
private Block block;
public Account()
{
this.id = new BlockAccountId();
}
public void setBlock(Block pBlock) {
this.block = pBlock;
}
public Block getBlock() {
return this.block;
}
public String getAccountRole() {
return this.id.getAccountRole();
}
public void setAccountRole(String accountRole) {
this.id.setAccountRole(accountRole);
}
}
}