Java Hibernate:外键的列数错误

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

我在两个实体类User和Permission之间定义了多对多关系。用户有一个由username和countyId组成的主键组合,我的权限表有一个常规整数Id。表UserPermission有三个外键作为主键:username、countyId和permissionId

因为这是一个遗留数据库,所以我没有机会做正确的事情(™) 并在用户上生成一个整数主键

我在User.class中定义了如下多对多关系:

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

}