2011-03-10 213 views
2

我對JPA映射對特定關係有問題。 在我的MySQL數據庫中,我有關係3實體:JPA映射 - 關係中的複合鍵

USER 
USER_SERIAL_NUMBER VARCHAR(20) not null, 
..... VARCHAR(4) not null, 
..... VARCHAR(3) not null, 
..... VARCHAR(10) not null, 
primary key (USER_SERIAL_NUMBER) 
); 
OFFICE (
OFFICE_SERIAL_NUMBER VARCHAR(20) not null, 
TOWN VARCHAR(15) not null, 
YEAR VARCHAR(4) not null, 
DESCRIPTION VARCHAR(200) not null, 
NOTE VARCHAR(100) not null, 
CREATION_DATE DATE not null, 
LAST_UPDATE_DATE DATE not null, 
primary key (OFFICE_SERIAL_NUMBER) 
); 

ROLE_TYPE (
ROLE_ID BIGINT not null, 
DESCRIPTION VARCHAR(20) not null, 
CREATION_DATE DATE not null, 
LAST_UPDATE_DATE DATE not null, 
primary key (ROLE_ID) 
); 

和關係表

ROLE (
ROLE_ID BIGINT not null, 
USER_SERIAL_NUMBER VARCHAR(20) not null, 
OFFICE_SERIAL_NUMBER VARCHAR(20) not null, 
YEAR VARCHAR(4) not null, 
CREATION_DATE DATE not null, 
LAST_UPDATE_DATE DATE not null, 
primary key (ROLE_ID, USER_SERIAL_NUMBER, OFFICE_SERIAL_NUMBER, YEAR) 
); 

在關係表我有3個外鍵和一個本地密鑰組合鍵(在年), ,因爲用戶可以在特定年份在特定辦公室有更多(不同)的角色,但可能會在下一年更改(我必須維護歷史性角色)。

我已經做了很多嘗試,以在實體中映射這些表,但我還沒有找到正確的組合,以便一切正常。

我想在兩個方向導航關係,所以我需要知道在特定的辦公室中有多少人是具有特定角色的用戶,但我還需要知道有多少辦公室在特定的辦公室工作用戶,他有什麼作用。

下面是Java代碼:

@Entity 
@Scope(ScopeType.CONVERSATION) 
@Name("role") 
@Table(name = "ROLE") 
@IdClass(RolePK.class) 
public class Role implements Serializable { 

private static final long serialVersionUID = 111111111L; 

@Id 
@OneToOne 
@Column(name="USER_SERIAL_NUMBER") 
private User User; 

@Id 
@OneToOne 
@Column(name="OFFICE_SERIAL_NUMBER") 
private Office office; 

@Id 
@OneToOne 
@Column(name="ROLE_ID") 
private RoleType roleType; 

@Id 
@Column(name = "YEAR", length = 4, nullable = false) 
private String year; 
@Temporal(TemporalType.TIMESTAMP) 
@Column(name = "CREATION_DATE", nullable = false) 
private Date creationDate; 

@Temporal(TemporalType.TIMESTAMP) 
@Column(name = "LAST_UPDATE_DATE", nullable = false) 
private Date lastUpdateDate; 

… getter and setter … 
… equals and hash code … 
… toString … 
} 

@Name("rolePK") 
public class RolePK implements Serializable { 

private static final long serialVersionUID = 2222222222222L; 

private String office; 
private Long roleType; 
private String User; 
private String year; 

public RolePK() { 

… getter and setter … 
… equals and hash code … 
… toString … 
} 
@Entity 
@Scope(ScopeType.CONVERSATION) 
@Name("user") 
@Table(name = "USER") 
public class User implements Serializable { 

private static final long serialVersionUID = 333333333333L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "USER_SERIAL_NUMBER", length = 20, nullable = false) 
private String serialNumber; 

… other properties… 

@OneToMany(mappedBy="user") 
private Collection<Role> roleCollection; 

… getter and setter … 
… equals and hash code … 
… toString … 


@Entity 
@Scope(ScopeType.CONVERSATION) 
@Name("office") 
@Table(name = "OFFICE") 
public class Office implements Serializable { 

private static final long serialVersionUID = 55555555555555555L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name="OFFICE_SERIAL_NUMBER", length=20, nullable=false) 
private String officeSerialNumber; 
… other properties… 

@OneToMany(mappedBy="office") 
private Collection<Role> roleCollection; 

… getter and setter … 
… equals and hash code … 
… toString … 

@Entity 
@Scope(ScopeType.CONVERSATION) 
@Name("roleType") 
@Table(name = "ROLE_TYPE") 
public class RoleType implements Serializable { 

private static final long serialVersionUID = 44444444444444444L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "ROLE_TYPE_ID", nullable = false) 
private Long id; 
… other properties… 

@OneToMany(mappedBy="roleType") 
private Collection<Role> roleCollection; 

… getter and setter … 
… equals and hash code … 
… toString … 

我試圖實施該解決方案(我已經嘗試過),但我仍然有配置問題。 在這個特定的配置中,我遇到的錯誤是當Hibernate嘗試創建查詢時,似乎無法生成正確的查詢。 特別是,我有不等於關係表的列的名稱的屬性的名稱。 我嘗試使用註釋來指定要在其上綁定屬性的列的名稱,但使用屬性名稱而不是列的名稱生成查詢。因此,系統引發異常,具體爲:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:未知列'roleco0_.user'in'字段列表'。

有人可以幫助我嗎? 在此先感謝

回答

4

爲什麼不在自己生成的角色表中引入自動生成的ID以及元組(roleId,use,office,year)上的唯一約束。這會讓事情變得簡單得多。

如果你確實想繼續使用這個組合主鍵,那麼你應該閱讀http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id,它以一個包含關聯的嵌入ID的例子結束。但要小心你的關聯:他們應該是ManyToOne,而不是OneToOne,因爲用戶(例如)可以被多個角色引用。

你應該這樣有

@Embeddable 
public class RoleId { 
    @ManyToOne 
    private User user; 

    @ManyToOne 
    private Office office; 

    @ManyToOne 
    private RoleType roleType; 

    private int year; 

    // constructor, getters, equals, hashCode 
} 

@Entity 
public class Role { 
    @EmbeddedId 
    private RoleId id; 

    private Date creationDate; 
    // ... 
}