java - 如何使用注释在 Hibernate 中表示复合键?

标签 java hibernate persistence

所以我从我的数据库中对一些表进行了逆向工程,当我尝试将我的对象保存到数据库时,我收到以下错误:

初始 SessionFactory 创建失败。org.hibernate.AnnotationException:从 com.mycode.Account 引用 com.mycode.Block 的外键列数错误。应该是 2 线程“main”中的异常 java.lang.ExceptionInInitializerError

Domain 对象是 Block,其中包含许多 Account 对象:

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "Block")
public Set<EAccount> getAccounts() {
    return this.Accounts;
}

Account 有一个由 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;
}

所以我想知道。如何在 blockOid 上链接表 block 和帐户,但仍确保帐户表同时具有 blockOid 和 accountRole 作为复合键。

任何示例将不胜感激!

注意这是 block (一个)到帐户(多个)的关系。

谢谢

最佳答案

最简单的方法是将您的关联直接放在嵌入的 id 组件中。

Hibernate reference documentation

例子(只写重要的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
}

对应的数据库表是:

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`)
)

关于java - 如何使用注释在 Hibernate 中表示复合键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7080611/

相关文章:

java - 来自LocalSessionFactoryBuilder的IllegalStateException

mysql - 插入日期字段mysql、struts2 spring hibernate

ruby-on-rails - :autosave property of has_many associations broken in Rails 2. 3.4?

persistence - 每月新增 20,000 个持久工作流实例的 WF 性能

java - 无法识别 Eclipselink 实体

java - Java wait() 方法究竟是如何工作的?

java - 递归处女通过碰撞检测获得堆栈溢出错误

Java-如何使用 java printf 打印空日期的空白

java - 您是否在 AndroidManifest.xml 中声明了此 Activity ?登录 Activity

java - Spring 3 注入(inject) Hibernate Session 的最佳方法