2009-09-27 28 views
6

He definido una relación muchos a muchos entre mis dos clases de entidad Usuario y Permiso. El usuario tiene una combinación de clave principal de nombre de usuario y countyId, y mi tabla de permisos tiene un ID entero regular. La tabla UserPermission tiene las tres claves foráneas como clave principal: username, countyId y permissionId.Hibernar: La clave externa tiene el número incorrecto de columnas

Dado que esta es una base de datos heredada, no tendré la oportunidad de hacer lo correcto (™) y crear una clave primaria entera en Usuario.

he definido la relación de muchos a muchos como esto en 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; 

Permission.class dice esto:

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "permissions", targetEntity = User.class) 
private Collection<User> users; 

pensé que éste era el camino a seguir , pero cuando el fuego de mi contexto primavera que utiliza Hibernate 3, me sale:

Caused by: org.hibernate.AnnotationException: A Foreign key refering com.mydomain.data.entities.User from com.mydomain.data.entities.Permission has the wrong number of column. should be 1 

¿Qué he hecho mal en mi Annot ación? Debe ser 2, no 1.


Actualización:

Arthur sugirió agrego referencedcolumnname, pero eso me dio una nueva excepción:

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 

En su petición, aquí seguir el código : Permission.Class:

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 **/ 
} 

y 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 **/ 
} 

Saludos

Nik

+0

Hola, he tenido el mismo problema, pero siguiendo su ejemplo, yo estoy recibiendo este error: referencias una entidad desconocida: java.lang.String. En mi caso, el condado sería de tipo String. –

Respuesta

5

Con el fin de resolver referencedcolumnname excepción

En sitúan al usuario

@ManyToMany(cascade={CascadeType.PERSIST, cascadeType.MERGE}) 
private Collection<Permission> permissions; 

Y en Permiso

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

clase UserId

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 
    } 

} 

A continuación, en la clase de usuario poner

@Entity 
@Table(name="tblUser") 
@IdClass(UserId.class) 
public class User ... { 

    @Id 
    private String username; 

    @Id 
    private Integer countyId; 

} 

cordiales,

+0

Entonces, para que quede claro, ¿nombre es la columna de la tabla en la tabla de unión mientras que el nombre de columna referenciado es la columna de la tabla en la tabla de entidad? De todos modos, al agregar el nombre de columna referenciado, obtengo "Causado por: org.hibernate.AnnotationException: referenceColumnNames (username, countyId) of com.mydomain.data.entities.Permission.permissions que hace referencia a com.mydomain.data.entities.Usuario no asignado a una sola propiedad "que es gracioso porque 'permisos' pertenece a la clase Usuario, no a la clase Permiso – niklassaers

+0

Por cierto, ¿por qué eliminaste targetEntity = Permiso.clase? – niklassaers

+0

Solo un momento. Si declaras generuc tipo Colección y la Colección targetEntity no es necesario. voy a comprobar si en su primera duda –

Cuestiones relacionadas