2011-03-10 151 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; 
    // ... 
}