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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 18:33:12  来源:igfitidea点击:

How to Represent Composite keys in Hibernate using Annotations?

javahibernatepersistence

提问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

休眠参考文档

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);
}

}

}