2012-05-24 189 views
0

嘿人我一直在尋找通過互聯網對於沒有成功以下問題......JPA - Hibernate的多對多關係保存

嗯...我測試白衣Hibernate和JPA註解,我已經開發一個常見的用戶案例ManyToMany關係。我試圖挽救與現有組的新用戶和測試情況下拋出一個異常,請參閱測試代碼和異常*如下:

PD。看着查詢在這種情況下,怪異的行爲是它的supossed在這個測試中的邏輯路徑的第一種方法的查找持續組,因爲他們退出已經保存新的用戶記錄在其表和鏈接表中插入新記錄..但它是像Hibernate假設組是新的記錄,並嘗試將它們分組表,當然這是拋出重複異常......但我還沒有想通出來呢......

什麼我可不可以做?我在這裏做錯了什麼?

在此先感謝。

@Test 
    public void guardarUsuario(){ 
     assertThat(servicio, is(notNullValue())); 
     Usuario u = new Usuario(); 
     u.setNombre("Elsy"); 
     u.setApellido("Cadenas"); 
     u.setCedula("4375792");  

     List<Grupo> grupos = servicio.buscarGrupos(); 

     u.getGrupos().addAll(grupos); 

     servicio.guardarUsuario(u); 


    } 

Hibernate: select grupo0_.nombre as nombre1_, grupo0_.descripcion as descripc2_1_ from public.grupo grupo0_ 
Hibernate: select usuarios0_.idgrupo as idgrupo1_1_, usuarios0_.idusuario as idusuario1_, usuario1_.cedula as cedula0_0_, usuario1_.apellido as apellido0_0_, usuario1_.nombre as nombre0_0_, usuario1_.version as version0_0_ from usuario_grupo usuarios0_ inner join public.usuario usuario1_ on usuarios0_.idusuario=usuario1_.cedula where usuarios0_.idgrupo=? 
Hibernate: select usuarios0_.idgrupo as idgrupo1_1_, usuarios0_.idusuario as idusuario1_, usuario1_.cedula as cedula0_0_, usuario1_.apellido as apellido0_0_, usuario1_.nombre as nombre0_0_, usuario1_.version as version0_0_ from usuario_grupo usuarios0_ inner join public.usuario usuario1_ on usuarios0_.idusuario=usuario1_.cedula where usuarios0_.idgrupo=? 
Hibernate: select usuario0_.cedula as cedula0_0_, usuario0_.apellido as apellido0_0_, usuario0_.nombre as nombre0_0_, usuario0_.version as version0_0_ from public.usuario usuario0_ where usuario0_.cedula=? 
Hibernate: insert into public.usuario (apellido, nombre, version, cedula) values (?, ?, ?, ?) 
Hibernate: insert into public.grupo (descripcion, nombre) values (?, ?) 
Hibernate: insert into public.grupo (descripcion, nombre) values (?, ?) 
2469 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23505 
2469 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Batch entry 0 insert into public.grupo (descripcion, nombre) values ('usuarios', 'USUARIO') was aborted. Call getNextException to see the cause. 
2469 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23505 
2469 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: duplicate key value violates unique constraint "pk_grupo" 

User.class

@Entity() 
@Table(name = "usuario", schema = "public") 
@NamedQuery(name = "Usuario.findByCedula", query = "select u from Usuario u where u.cedula = :cedula") 
public class Usuario implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private String nombre; 
    private String apellido; 
    @Id 
    @Column(length = 8) 
    private String cedula; 
    @Version 
    private Integer version; 
    @JoinTable(name = "usuario_grupo", joinColumns = { @JoinColumn(name = "idusuario", referencedColumnName = "cedula") }, inverseJoinColumns = { @JoinColumn(name = "idgrupo", referencedColumnName = "nombre") }) 
    @ManyToMany(cascade = { CascadeType.PERSIST }, fetch = FetchType.LAZY) 
    private Set<Grupo> grupos = new HashSet<Grupo>(); 

    Constructors... Getters and setters... 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((cedula == null) ? 0 : cedula.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Usuario other = (Usuario) obj; 
     if (cedula == null) { 
      if (other.cedula != null) 
       return false; 
     } else if (!cedula.equals(other.cedula)) 
      return false; 
     return true; 
    } 

    public void addGrupo(Grupo g) { 
     if (!getGrupos().contains(g)) { 
      getGrupos().add(g); 
     } 
     if (!g.getUsuarios().contains(this)) { 
      g.getUsuarios().add(this); 
     } 
    } 

Group.class

@Entity 
@Table(name="grupo", schema="public") 
public class Grupo implements Serializable{ 


    private static final long serialVersionUID = 1L; 
    @Id 
    private String nombre; 
    private String descripcion; 
    @JoinTable(name="usuario_grupo", joinColumns={@JoinColumn(name="idgrupo")}, [email protected](name="idusuario")) 
    @ManyToMany(cascade={CascadeType.PERSIST}, fetch=FetchType.EAGER) 
    private Set<Usuario> usuarios = new HashSet<Usuario>(); 

    Constructors... Getters and Setters... 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result 
       + ((descripcion == null) ? 0 : descripcion.hashCode()); 
     result = prime * result + ((nombre == null) ? 0 : nombre.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Grupo other = (Grupo) obj; 
     if (descripcion == null) { 
      if (other.descripcion != null) 
       return false; 
     } else if (!descripcion.equals(other.descripcion)) 
      return false; 
     if (nombre == null) { 
      if (other.nombre != null) 
       return false; 
     } else if (!nombre.equals(other.nombre)) 
      return false; 
     return true; 
    } 
} 

SQL:

USER Table 


-- Table: usuario 

-- DROP TABLE usuario; 

CREATE TABLE usuario 
(
    nombre character varying(50), 
    apellido character varying(50), 
    cedula character varying(8) NOT NULL, 
    "version" integer, 
    CONSTRAINT pk_usuario PRIMARY KEY (cedula) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE usuario OWNER TO postgres; 

組表

-- Table: grupo 

-- DROP TABLE grupo; 

CREATE TABLE grupo 
(
    nombre character varying(20) NOT NULL, 
    descripcion character varying(50), 
    CONSTRAINT pk_grupo PRIMARY KEY (nombre) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE grupo OWNER TO postgres; 

鏈接表

-- Table: usuario_grupo 

-- DROP TABLE usuario_grupo; 

CREATE TABLE usuario_grupo 
(
    idusuario character varying(8) NOT NULL, 
    idgrupo character varying(20) NOT NULL, 
    CONSTRAINT pk_id_grupo PRIMARY KEY (idusuario, idgrupo), 
    CONSTRAINT fk_miembro_grupo FOREIGN KEY (idgrupo) 
     REFERENCES grupo (nombre) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT fk_miembro_usuario FOREIGN KEY (idusuario) 
     REFERENCES usuario (cedula) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE usuario_grupo OWNER TO postgres; 
+0

能否請您發表您通過servicio.guardarUsuario(U)調用該服務的代碼? – Gamb

回答

0

我覺得Usuario和了Grupo之間的多對多關係可能會堅持那些已經堅持上了Grupo表值。當它說PK的唯一約束被破壞時,這個例外是非常自我描述的。

不能級聯persist操作,你應該罰款。