Java Hibernate:外键的列数错误
我在两个实体类User和Permission之间定义了多对多关系。用户有一个由username和countyId组成的主键组合,我的权限表有一个常规整数Id。表UserPermission有三个外键作为主键:username、countyId和permissionId 因为这是一个遗留数据库,所以我没有机会做正确的事情(™) 并在用户上生成一个整数主键 我在User.class中定义了如下多对多关系:Java Hibernate:外键的列数错误,java,hibernate,spring,foreign-keys,Java,Hibernate,Spring,Foreign Keys,我在两个实体类User和Permission之间定义了多对多关系。用户有一个由username和countyId组成的主键组合,我的权限表有一个常规整数Id。表UserPermission有三个外键作为主键:username、countyId和permissionId 因为这是一个遗留数据库,所以我没有机会做正确的事情(™) 并在用户上生成一个整数主键 我在User.class中定义了如下多对多关系: @ManyToMany(targetEntity=Permission.class, casc
@ManyToMany(targetEntity=Permission.class, cascade={ CascadeType.PERSIST, CascadeType.MERGE } )
@JoinTable(name="tblUserPermission",
joinColumns = { @JoinColumn(name="username"), @JoinColumn(name="countyId") },
inverseJoinColumns = { @JoinColumn(name="permissionId") })
private Collection<Permission> permissions;
我在注释中做错了什么?应该是2,而不是1
更新: Arthur建议我添加referencedColumnName,但这给了我一个新的例外:
Caused by: org.hibernate.AnnotationException: referencedColumnNames(username, countyId) of com.mydomain.data.entities.Permission.permissions referencing com.mydomain.data.entities.User not mapped to a single property
根据他的要求,以下是代码:
权限。类别:
package com.mydomain.data.entities;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.*;
import org.hibernate.annotations.ForeignKey;
@Entity
@Table(name = "tblPermission")
public class Permission extends PublishableEntityImpl implements Serializable, Cloneable {
private static final long serialVersionUID = 7155322069731920447L;
@Id
@Column(name = "PermissionId", length = 8, nullable = false)
private String PermissionId = "";
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "CountyId", nullable = false)
@ForeignKey(name="FK_CountyID")
private County county;
@Column(name = "Permission", nullable = true)
private Integer permission = 1;
@ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE},
mappedBy = "Permissions",
targetEntity = Item.class )
private Collection<Item> items;
@ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE},
mappedBy = "Permissions",
targetEntity = User.class )
private Collection<User> users;
/** Getters and Setters **/
}
包com.mydomain.data.entities;
导入java.io.Serializable;
导入java.util.Collection;
导入javax.persistence.*;
导入org.hibernate.annotations.ForeignKey;
@实体
@表(name=“tblPermission”)
公共类权限扩展PublishableEntityImpl实现可序列化、可克隆{
私有静态最终长serialVersionUID=7155322069731920447L;
@身份证
@列(name=“PermissionId”,长度=8,可空=false)
私有字符串PermissionId=“”;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“CountyId”,nullable=false)
@外键(name=“FK_CountyID”)
私立县;
@列(name=“Permission”,nullable=true)
私有整数权限=1;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},
mappedBy=“权限”,
targetEntity=Item.class)
私人收藏物品;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},
mappedBy=“权限”,
targetEntity=User.class)
私人收藏用户;
/**接球手和接球手**/
}
和User.class
package com.mydomain.data.entities;
import java.util.*;
import java.io.Serializable;
import javax.persistence.*;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.IndexColumn;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
@Entity
@Table(name = "tblUser")
public class User extends PublishableEntityImpl implements Serializable, Cloneable {
@Id
@Column(name = "CountyId", nullable = false)
private Integer countyId;
@Id
@Column(name = "Username", length = 25, nullable = false)
private String username;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "CountyId", nullable = false, insertable=false, updatable=false)
@ForeignKey(name="FK_CountyID")
private County county;
@Column(name = "Name", length = 50, nullable = true)
private String name;
@Column(name = "Password", length = 30, nullable = true)
private String password;
@Column(name = "Role", nullable = false)
private Integer role;
@ManyToMany(targetEntity=Permission.class,
cascade={ CascadeType.PERSIST, CascadeType.MERGE } )
@JoinTable(name="tblUserPermission",
joinColumns = { @JoinColumn(name="Username", referencedColumnName="Username"), @JoinColumn(name="CountyId", referencedColumnName="CountyId") },
inverseJoinColumns = { @JoinColumn(name="PermissionId", referencedColumnName="PermissionId") })
private Collection<Permission> permissions;
@OneToMany(fetch=FetchType.LAZY, mappedBy="county")
@IndexColumn(name="version")
private List<Version> versions;
/** Getters and setters **/
}
包com.mydomain.data.entities;
导入java.util.*;
导入java.io.Serializable;
导入javax.persistence.*;
导入org.hibernate.annotations.ForeignKey;
导入org.hibernate.annotations.IndexColumn;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.GrantedAuthorityImpl;
导入org.springframework.security.core.userdetails.userdetails;
@实体
@表(name=“tblUser”)
公共类用户扩展PublishableEntityImpl实现可序列化、可克隆{
@身份证
@列(name=“CountyId”,null=false)
私有整数countyId;
@身份证
@列(name=“Username”,长度=25,可空=false)
私有字符串用户名;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“CountyId”,nullable=false,insertable=false,updateable=false)
@外键(name=“FK_CountyID”)
私立县;
@列(name=“name”,长度=50,可空=true)
私有字符串名称;
@列(name=“Password”,长度=30,可空=true)
私有字符串密码;
@列(name=“Role”,nullable=false)
私有整数角色;
@ManyToMany(targetEntity=Permission.class,
cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name=“tblUserPermission”,
joinColumns={@JoinColumn(name=“Username”,referencedColumnName=“Username”),@JoinColumn(name=“CountyId”,referencedColumnName=“CountyId”),
inverseJoinColumns={@JoinColumn(name=“PermissionId”,referencedColumnName=“PermissionId”)}
私人收藏权限;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“county”)
@IndexColumn(name=“version”)
私人名单版本;
/**接球手和接球手**/
}
干杯
Nik以解决referencedColumnName异常 用户输入
@ManyToMany(cascade={CascadeType.PERSIST, cascadeType.MERGE})
private Collection<Permission> permissions;
然后在用户类中放入
@Entity
@Table(name="tblUser")
@IdClass(UserId.class)
public class User ... {
@Id
private String username;
@Id
private Integer countyId;
}
关于,因此,为了清楚起见,name是联接表中的表列,而referencedColumnName是实体表中的表列?无论如何,添加referencedColumnName“是由以下原因引起的:org.hibernate.AnnotationException:referencedColumnNames(用户名,countyId)未映射到单个属性的com.mydomain.data.entities.Permission.permissions引用com.mydomain.data.entities.User的这很有趣,因为“permissions”属于类用户,而不是类PermissionBTW,为什么要删除targetEntity=Permission.class?请稍等。如果您声明generuc类型集合,集合targetEntity不是必需的。我将检查您在Permission类中的第一个Do疑映射Pedby应该是Permission,而不是“P”ERMISSION在用户类中,在county propertyHello中删除nullable=false,我遇到了同样的问题,但按照您的示例,我得到了以下错误:引用未知实体:java.lang.String。在我的示例中,county将是字符串类型。
@ManyToMany(cascade={CascadeType.PERSIST, cascadeType.MERGE})
private Collection<Permission> permissions;
@ManyToMany(mappedBy="permissions")
@JoinTable(name="tblUserPermission",
joinColumns={@JoinColumn(name="permissionId", referencedColumnName="permissionId")},
inverseJoinColumns={
@JoinColumn(name="username", referencedColumnName="username"),
@JoinColumn(name="countyId", referencedColumnName="countyId")})
private Collection<User> users;
public class UserId implements Serializable {
private String username;
private Integer countyId;
// getter's and setter's
public boolean equals(Object o) {
if(o == null)
return false;
if(!(o instanceof UserId))
return false;
UserId id = (UserId) o;
if(!(getUsername().equals(id.getUsername()))
return false;
if(!(getCountyId().equals(id.getCountyId()))
return false;
return true;
}
public int hachcode() {
// hashcode
}
}
@Entity
@Table(name="tblUser")
@IdClass(UserId.class)
public class User ... {
@Id
private String username;
@Id
private Integer countyId;
}