mysql 多对多映射_JPA 一对多单向 映射至Mysql的问题
角色Role与权限Authority,我设计成一对多单向关联,数据库mysql:
//Role.java:
@Entity
public class Role implements Serializable {
private Integer roleid;
private String rolename;
private String description;
private Set auths = new HashSet();
@Column
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Id
@GeneratedValue
public Integer getRoleid() {
return roleid;
}
public void setRoleid(Integer roleid) {
this.roleid = roleid;
}
@Column
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
//一对多单向关联
@OneToMany(cascade = CascadeType.REFRESH, fetch=FetchType.EAGER)
@JoinTable(name = "role_auth", joinColumns = @JoinColumn(name = "roleid"),
inverseJoinColumns = @JoinColumn(name = "authorityid"))
public Set getAuths() {
return auths;
}
public void setAuths(Set auths) {
this.auths = auths;
}
// 添加权限
public void addAuth(Authority auth) {
this.auths.add(auth);
}
@Override
public int hashCode() {
...
}
@Override
public boolean equals(Object obj) {
...
}
}
//Authority.java:
@Entity
public class Authority implements Serializable {
private Integer authorityid;
// 范围
private Range range;
// 动作
private Action action;
public Authority() {}
public Authority(Range range, Action action) {
this.range = range;
this.action = action;
}
@ManyToOne
@JoinColumn(name="actionid",
referencedColumnName="actionid")
public Action getAction() {
return action;
}
public void setAction(Action action) {
this.action = action;
}
@Id
@GeneratedValue
public Integer getAuthorityid() {
return authorityid;
}
public void setAuthorityid(Integer authorityid) {
this.authorityid = authorityid;
}
@ManyToOne
@JoinColumn(name="rangeid",
referencedColumnName="rangeid")
public Range getRange() {
return range;
}
public void setRange(Range range) {
this.range = range;
}
@Override
public int hashCode() {
...
}
@Override
public boolean equals(Object obj) {
...
}
}
生成的中间表为role_auth,查看建表语句:
mysql> show create table user_role;
| Table | Create Table
| user_role | CREATE TABLE `user_role` (
`userid` int(11) NOT NULL,
`roleid` int(11) NOT NULL,
PRIMARY KEY (`userid`,`roleid`),
UNIQUE KEY `roleid` (`roleid`),//roleid为什么具有唯一性???
KEY `FK143BF46A889EC6EB` (`userid`),
KEY `FK143BF46A83497181` (`roleid`),
CONSTRAINT `FK143BF46A83497181` FOREIGN KEY (`roleid`) REFERENCES `role` (`rol
eid`),
CONSTRAINT `FK143BF46A889EC6EB` FOREIGN KEY (`userid`) REFERENCES `user` (`use
rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
1 row in set (0.00 sec)
如上红色部分,roleid具有唯一性,这样我在插入角色时就会出现类似“Duplicate entry '2' for key 2”的错误。
该怎么改呢??
问题补充:sorry,sql语句贴错了,
mysql> show create table role_auth;
| Table | Create Table
| role_auth | CREATE TABLE `role_auth` (
`roleid` int(11) NOT NULL,
`authorityid` int(11) NOT NULL,
PRIMARY KEY (`roleid`,`authorityid`),
UNIQUE KEY `authorityid` (`authorityid`), //这里被设定为具有唯一性?!~
KEY `FK13FEEFD183497181` (`roleid`),
KEY `FK13FEEFD1270B3A27` (`authorityid`),
CONSTRAINT `FK13FEEFD1270B3A27` FOREIGN KEY (`authorityid`) REFERENCES `author
ity` (`authorityid`),
CONSTRAINT `FK13FEEFD183497181` FOREIGN KEY (`roleid`) REFERENCES `role` (`rol
eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
1 row in set (0.00 sec)
问题补充:to xiaolongfeixiang: 这个int型的id,我是不是得在
@JoinTable(name = "role_auth", joinColumns = @JoinColumn(name = "roleid"),
inverseJoinColumns = @JoinColumn(name = "authorityid"))
中添加?!怎么添加,谢谢!
问题补充:to xiaolongfeixiang:额,我有点儿晕了。不过还是先谢谢你哈。
Authority里不是已经有一个Integer authorityid了吗,还要一个int型的id?你说“那个是约束的要求”,是指在“一对多”关系中“多”都需要这样吗?
问题补充:我在Hibernate的文档中找到两段话:
2.2.5.3.2.3. Unidirectional with join table //one2many单向关联(有中间表)
A unidirectional one to many with join table is much preferred. This association is described through an @JoinTable.
@Entity
public class Trainer {
@OneToMany
@JoinTable(
name="TrainedMonkeys",
joinColumns = @JoinColumn( name="trainer_id"),
inverseJoinColumns = @JoinColumn( name="monkey_id")
)
public Set<Monkey> getTrainedMonkeys() {
...
}
@Entity
public class Monkey {
... //no bidir
}
Trainer describes a unidirectional relationship with Monkey using the join table TrainedMonkeys, with a foreign key trainer_id to Trainer (joinColumns) and a foreign key monkey_id to Monkey (inversejoinColumns).
2.2.5.3.2.4. Defaults //默认,无@JoinTable的情况
Without describing any physical mapping, a unidirectional one to many with join table is used. The table name is the concatenation of the owner table name, _, and the other side table name. The foreign key name(s) referencing the owner table is the concatenation of the owner table, _, and the owner primary key column(s) name. The foreign key name(s) referencing the other side is the concatenation of the owner property name, _, and the other side primary key column(s) name. A unique constraint is added to the foreign key referencing the other side table to reflect the one to many.//这最后一句话就是说那个唯一性的,可是我的有@JoinTable啊。
@Entity
public class Trainer {
@OneToMany
public Set<Tiger> getTrainedTigers() {
...
}
@Entity
public class Tiger {
... //no bidir
}
Trainer describes a unidirectional relationship with Tiger using the join table Trainer_Tiger, with a foreign key trainer_id to Trainer (table name, _, trainer id) and a foreign key trainedTigers_id to Monkey (property name, _, Tiger primary column).