How to Represent Composite keys in Hibernate using Annotations?

放肆的年华 提交于 2019-12-09 14:06:09

问题


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

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:

@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.

Any examples would be greatly appreciated!

N.B this is a Block (One) to Account (Many) relationship.

Thanks


回答1:


The easiest is to place your association directly in the embedded id component.

Hibernate reference documentation

  • Section 5.1.2.1.1. id as a property using a component type ()

Example (Only write the important getter() and 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`)
)



回答2:


based on hibernate documentation here's the link

based on it you can do the following :

@Entity public class Account {

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

}



来源:https://stackoverflow.com/questions/7080611/how-to-represent-composite-keys-in-hibernate-using-annotations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!