2011-08-16 1 views
1

그래서 난 내 DB에서 일부 테이블을 설계 및 리버스 나는 다음과 같은 오류 얻을 DB 내 개체를 저장하려고하면어노테이션을 사용하여 Hibernate에서 복합 키를 표현하는 방법?

초기 SessionFactory를 생성 failed.org.hibernate.AnnotationException을 : 외래 키 다스의 com.mycode com.mycode.Account에서 .Block의 열 수가 잘못되었습니다.

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

계정 아이디와 역할의 복합 키가 : 계정 개체의 수를 포함

도메인 객체는 블록 있습니까 스레드 "주요"java.lang.ExceptionInInitializerError 2 예외해야한다. 이것은 별도의 클래스에서 설정되었습니다 :

@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에 연결하고 계정을 연결하려면 어떻게해야합니까?하지만 계정 테이블에 blockOid와 accountRole이 모두 복합 키로 설정되어 있는지 확인하십시오.

예를 들어 주시면 감사하겠습니다.

N.B 이것은 블록 (1) - 계정 (다수) 관계입니다.

감사

답변

4

가장 쉬운 임베디드 ID 구성 요소에서 직접 연결을 배치하는 것입니다.

Hibernate reference documentation

예 (전용 (중요한 게터 쓰기)와 세터())

@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`) 
) 
+0

감사합니다. 사실 원래이 객체를 가지고 있지만 Block 객체에 추가로 @id가 있습니다. 그런 다음 오류 메시지가 날 던져서 AccountId 클래스 (포함 된 복합 ID)라고 생각하게 만들었습니다. 어떻게하면 최대 절전 모드로 리버스 엔지니어링을 할 수 있는지보아야 할 것 같습니다. consise 대답을 주셔서 감사합니다 – Mick

+1

문제 없어요! –

+0

좋은 답변입니다. 제약이없는 일반적인 복합 키의 경우 복합 키의 일부인 필드에 대해 각 getter 메서드에 @Id 주석을 추가하면 Hibernate를 만족시키기에 충분하므로 클래스 파일이 어떻게 작동하는지에 대해 불평하지 않습니다. 실제로 데이터베이스를 조회 한 후에 데이터베이스 메타 데이터를 반영합니다. 물론 ManyToOne (...) 등이있는 경우 다른 관계를 지정할 수 있어야합니다.하지만 가지고있는 것이 모두 복합 키이고 Hibernate가 당신을 혼자 남기고 싶다면, 충분해야합니다. –

0

여기 link

입니다

을 기반으로 다음을 수행 할 수 있습니다.

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

} 이것에 대한