Foros del Web » Programación para mayores de 30 ;) » Java »

Guardar OneToMany Hibernate

Estas en el tema de Guardar OneToMany Hibernate en el foro de Java en Foros del Web. Hola a todos, quería hacerles la siguiente consulta: Estoy usando hibernate y hasta ahora no he tenido problemas excepto para guardar una entidad que tiene ...
  #1 (permalink)  
Antiguo 17/04/2017, 22:25
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Guardar OneToMany Hibernate

Hola a todos, quería hacerles la siguiente consulta: Estoy usando hibernate y hasta ahora no he tenido problemas excepto para guardar una entidad que tiene una colección onetomany, y no he podido guardar, pongo el código:

Código Java:
Ver original
  1. public class Subasta implements Serializable
  2. {
  3.     @Id
  4.     @GeneratedValue(strategy = GenerationType.IDENTITY)
  5.     @Column(name = "suId")
  6.     private int id;
  7.     @Column(name = "suFecha")
  8.     private GregorianCalendar fecha;
  9.     @ManyToOne(cascade = CascadeType.ALL)
  10.     @JoinColumn(name = "dirId")
  11.     private Direccion direccion;
  12.     @ManyToOne(cascade = CascadeType.ALL)
  13.     @JoinColumn(name = "subId")
  14.     private Subastador subastador;
  15.     //aqui empiezan mis problemas
  16.     @OneToMany(mappedBy = "subasta",cascade = CascadeType.ALL)
  17.     private List<Venta>ventas;
  18.     ..........................
  19.    
  20.     public void addVenta(Venta v){
  21.         v.setSubasta(this);
  22.         ventas.add(v);        
  23.     }
  24.     public void delVenta(Venta v){
  25.         ventas.remove(v);
  26.     }
  27. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import javax.persistence.*;
  5. @Table(name = "ventas")
  6. public class Venta implements Serializable
  7. {
  8.     @EmbeddedId
  9.     private VentaKey key;
  10.     @JoinColumns({
  11.         @JoinColumn(name = "SuId",referencedColumnName = "suId"),
  12.     })
  13.     @ManyToOne(cascade = CascadeType.ALL)
  14.     private Subasta subasta;
  15.     @ManyToOne(cascade = CascadeType.ALL)
  16.     @JoinColumn(name = "estId")
  17.     private Estado obje;
  18.     @OneToMany(cascade = CascadeType.ALL, mappedBy = "venta")    
  19.     private List<Registro>registros;
  20.     public Subasta getSubasta() {
  21.         return subasta;
  22.     }
  23.     public void setSubasta(Subasta subasta) {
  24.         this.subasta = subasta;
  25.     }
  26.     public VentaKey getKey() {
  27.         return key;
  28.     }
  29.     public void setKey(VentaKey key) {
  30.         this.key = key;
  31.     }    
  32.     public Estado getObje() {
  33.         return obje;
  34.     }
  35.     public void setObje(Estado obje) {
  36.         this.obje = obje;
  37.     }
  38.     public List<Registro> getRegistros() {
  39.         return registros;
  40.     }
  41.     public void setRegistros(List<Registro> registros) {
  42.         this.registros = registros;
  43.     }    
  44.     public Venta() { }        
  45.     public Venta(Subasta xobjs, Artefacto xobja, Estado obje) {
  46.         this.key = new VentaKey(xobjs,xobja);
  47.         this.obje = obje;
  48.     }    
  49.     @Override
  50.     public boolean equals(Object obj) {
  51.         if(obj instanceof Venta){
  52.             Venta v  =(Venta)obj;
  53.             return v.key.getObja() == this.key.getObja() && v.obje.equals(this.obje);
  54.         } else {
  55.             return false;
  56.         }
  57.     }
  58.     @Override
  59.     public int hashCode() {
  60.         int hash = 17;
  61.         hash = 31 * hash + this.key.getObja().hashCode();
  62.         hash = 31 * hash + this.obje.hashCode();
  63.         return hash;
  64.     }
  65.     @Override
  66.     public String toString() {
  67.         return this.key.getObja().getNombre() + " - estado: " + this.obje.getNombre();
  68.     }  
  69. }

Pero en el formulario lo tengo así:

Código Java:
Ver original
  1. private void btnaceptarActionPerformed(java.awt.event.ActionEvent evt) {                                          
  2.         if(this.dtfecsubasta.getCalendar() == null || this.txtdirsubasta.getText().isEmpty() || this.txtsubsubasta.getText().isEmpty()){
  3.             Mensajes.MostrarAdvertencia("Ingrese los datos obligatorios (*)");
  4.         } else {
  5.             if(accion.equals("crear")){
  6.                 try {
  7.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  8.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  9.                     Subasta sub = new Subasta(0, this.getDateTime(), d, s);                    
  10.                     sub.setVentas(((ModeloVenta)mv.getModelo()).getDatos().toList());                    
  11.                     FacadeContr.getInstance().manSubastas().add(sub);                
  12.                     Mensajes.MostrarConfirmacion("Subasta Creada");                    
  13.                     btncancelarActionPerformed(evt);
  14.                 } catch (Exception ex) {
  15.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  16.                 }
  17.             } else {
  18.                 try {
  19.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  20.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  21.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);
  22.                     sub.setVentas(((ModeloVenta)mv.getModelo()).getDatos().toList());
  23.                     FacadeContr.getInstance().manSubastas().edit(sub);                
  24.                     Mensajes.MostrarConfirmacion("Subasta Editada");
  25.                     btncancelarActionPerformed(evt);
  26.                 } catch (Exception ex) {
  27.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  28.                 }
  29.             }            
  30.         }
  31.     }

Pero no me guarda las ventas de la subasta y no se que rayos hacer...

Espero sus respuestas y saludos.
  #2 (permalink)  
Antiguo 18/04/2017, 01:02
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Comprueba primero que las ventas se setean correctamente y luego asegúrate de que llegan al manager/dao.
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #3 (permalink)  
Antiguo 18/04/2017, 13:10
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Estuve mirando y si se setean sólo que cuando voy a guardar la subasta con las ventas me da este error:

ERROR: HHH000346: Error during managed flush [org.hibernate.exception.SQLGrammarException: could not execute statement]

Por otro lado cuando seteo las ventas en la subasta, el atributo subasta de la venta esta null, ahí tengo la duda de sí primero tengo guardar la subasta y después setear y llegar al manager.

Tengo una clase abstracta en la cual hago el CRUD:

Código Java:
Ver original
  1. package app.contr.util;
  2. import app.model.service.HibernateUtil;
  3. import org.hibernate.Session;
  4. import org.hibernate.query.Query;
  5. import up.max.proyectpages.structs.PagesList;
  6. public abstract class Controlador<T>
  7. {
  8.     Session ss = null;
  9.     public Controlador() {
  10.         ss = HibernateUtil.getInstance().getSession();
  11.     }
  12.     public void add(T entity) throws Exception{
  13.         if(checkUnique(entity)){
  14.             throw new Exception(this.checkUniqueMessage());
  15.         } else {
  16.             ss.beginTransaction();
  17.             ss.save(entity);
  18.             ss.getTransaction().commit();
  19.         }
  20.     }
  21.     ..............
  22.     protected abstract boolean checkUnique(T entity);
  23. }

y cuando heredo en una clase y redefino

Código Java:
Ver original
  1. @Override
  2.     protected boolean checkUnique(Rol entity) {
  3.         return findByX(entity.getNombre())!= null;
  4.     }
  5.     @Override
  6.     protected String checkUniqueMessage() {
  7.         return "El rol ya existe";
  8.     }

cuando no es necesario el unique le redefino con false.....

Espero sus respuestas y saludos
  #4 (permalink)  
Antiguo 19/04/2017, 01:02
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Según entiendo, subasta debería ser obligatorio en cada venta y mapearía la id de la subasta al atributo subasta de la venta, y ventas sería opcional en una subasta de forma que sí, primero tendrías que crear la subasta sin ventas y luego rellenar el atributo subasta de las ventas y actualizar la subasta con las ventas.
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #5 (permalink)  
Antiguo 19/04/2017, 20:12
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hey FuzzyLog verás intenté hacer unos pequeños cambios:

En el formulario, cuando creo por primera vez la subasta:

Código Java:
Ver original
  1. if(accion.equals("crear")){
  2.                 try {
  3.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  4.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  5.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);                    
  6.                     sub.setVentas(((ModeloVenta)mv.getModelo()).getDatos().toList());
  7.                     sub.getVentas().toList().forEach((v) -> {
  8.                         v.setSubasta(sub);
  9.                     });
  10.                     FacadeContr.getInstance().manSubastas().add(sub);                
  11.                     Mensajes.MostrarConfirmacion("Subasta Creada");                    
  12.                     btncancelarActionPerformed(evt);
  13.                 } catch (Exception ex) {
  14.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  15.                 }
  16.             }

y en la clase Venta:

Código Java:
Ver original
  1. public void setSubasta(Subasta subasta) {
  2.         this.subasta = subasta;
  3.         key.setObjs(subasta);
  4.     }

Pero me sigue dando este error:

ERROR: HHH000346: Error during managed flush [org.hibernate.exception.SQLGrammarException: could not execute statement]

Te pongo una imagen para que veas cómo tengo diseñado mi formulario, en este link:

http://imgur.com/a/KKSPe

Espero sus respuestas y saludos
  #6 (permalink)  
Antiguo 20/04/2017, 02:55
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Trata de sacar la traza completa del error. Lo más seguro es que te dé más información.

Por otra parte es posible que necesites ejecutar todo en transacciones separadas, para que hibernate haga commit del guardado de la subasta antes de insertar las ventas.
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #7 (permalink)  
Antiguo 20/04/2017, 21:00
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hey FuzzyLog depurando el sistema ahora no muestra elementos nulos en la clase Venta pero me da el mismo error, estoy comenzando a pensar que el problema está en la clase Venta o VentaKey (clase que uso para la relación N a N)

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import javax.persistence.*;
  5. @Table(name = "ventas")
  6. public class Venta implements Serializable
  7. {
  8.     @EmbeddedId
  9.     private VentaKey key;
  10.     @JoinColumns({
  11.         @JoinColumn(name = "SuId",referencedColumnName = "suId"),
  12.     })
  13.     @ManyToOne(cascade = CascadeType.ALL)
  14.     private Subasta subasta;
  15.     @ManyToOne(cascade = CascadeType.ALL)
  16.     @JoinColumn(name = "estId")
  17.     private Estado obje;
  18.     @OneToMany(cascade = CascadeType.ALL, mappedBy = "venta")    
  19.     private List<Registro>registros;
  20.     public Subasta getSubasta() {
  21.         return subasta;
  22.     }
  23.     public void setSubasta(Subasta subasta) {
  24.         this.subasta = subasta;
  25.     }
  26.     public VentaKey getKey() {
  27.         return key;
  28.     }
  29.     public void setKey(VentaKey key) {
  30.         this.key = key;
  31.     }    
  32.     public Estado getObje() {
  33.         return obje;
  34.     }
  35.     public void setObje(Estado obje) {
  36.         this.obje = obje;
  37.     }
  38.     public List<Registro> getRegistros() {
  39.         return registros;
  40.     }
  41.     public void setRegistros(List<Registro> registros) {
  42.         this.registros = registros;
  43.     }    
  44.     public Venta() { }        
  45.     public Venta(Subasta xobjs, Artefacto xobja, Estado obje) {
  46.         this.key = new VentaKey(xobjs,xobja);
  47.         this.subasta = xobjs;
  48.         this.obje = obje;
  49.     }    
  50.     @Override
  51.     public boolean equals(Object obj) {
  52.         if(obj instanceof Venta){
  53.             Venta v  =(Venta)obj;
  54.             return v.key.getObja() == this.key.getObja() && v.obje.equals(this.obje);
  55.         } else {
  56.             return false;
  57.         }
  58.     }
  59.     @Override
  60.     public int hashCode() {
  61.         int hash = 17;
  62.         hash = 31 * hash + this.key.getObja().hashCode();
  63.         hash = 31 * hash + this.obje.hashCode();
  64.         return hash;
  65.     }
  66.     @Override
  67.     public String toString() {
  68.         return this.key.getObja().getNombre() + " - estado: " + this.obje.getNombre();
  69.     }  
  70. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import javax.persistence.*;
  4. @Embeddable
  5. public class VentaKey implements Serializable
  6. {
  7.     @ManyToOne(cascade = CascadeType.ALL)
  8.     @JoinColumn(name = "suId")
  9.     private Subasta objs;
  10.     @ManyToOne(cascade = CascadeType.ALL)
  11.     @JoinColumn(name = "artId")
  12.     private Artefacto obja;
  13.     public Subasta getObjs(){
  14.         return objs;
  15.     }
  16.     public void setObjs(Subasta objs) {
  17.         this.objs = objs;
  18.     }
  19.     public Artefacto getObja() {
  20.         return obja;
  21.     }    
  22.     public void setObja(Artefacto obja) {
  23.         this.obja = obja;
  24.     }    
  25.     public VentaKey(){}
  26.     public VentaKey(Subasta xobjs, Artefacto xobja) {
  27.         this.objs = xobjs;
  28.         this.obja = xobja;
  29.     }
  30.     @Override
  31.     public boolean equals(Object obj){
  32.         if(obj instanceof VentaKey){
  33.             VentaKey id =(VentaKey)obj;
  34.             return id.objs.equals(this.objs) && id.obja.equals(this.obja);
  35.         } else {
  36.             return false;
  37.         }
  38.     }
  39.     @Override
  40.     public int hashCode(){
  41.         int hash = 17;
  42.         hash = 31 * hash + this.objs.hashCode();
  43.         hash = 31 * hash + this.obja.hashCode();
  44.         return hash;
  45.     }
  46. }

Por otro lado hice lo que me dijiste quedandome el formulario así:

Código Java:
Ver original
  1. private void btnaceptarActionPerformed(java.awt.event.ActionEvent evt) {                                          
  2.         if(this.dtfecsubasta.getCalendar() == null || this.txtdirsubasta.getText().isEmpty() || this.txtsubsubasta.getText().isEmpty()){
  3.             Mensajes.MostrarAdvertencia("Ingrese los datos obligatorios (*)");
  4.         } else {
  5.             if(accion.equals("crear")){
  6.                 try {
  7.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  8.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  9.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);
  10.                     FacadeContr.getInstance().manSubastas().add(sub);                
  11.                     Mensajes.MostrarConfirmacion("Subasta Creada");
  12.                     ventana.setTitle("Editar Subasta");
  13.                     accion = "editar";
  14.                     objs = FacadeContr.getInstance().manSubastas().findById(sub.getId());
  15.                 } catch (Exception ex) {
  16.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  17.                 }
  18.             } else {
  19.                 try {
  20.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  21.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  22.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);
  23.                     sub.setVentas(objs.getVentas().toList());
  24.                     sub.getVentas().toList().forEach((v) -> {
  25.                         v.setSubasta(sub);
  26.                     });
  27.                     FacadeContr.getInstance().manSubastas().edit(sub);                
  28.                     Mensajes.MostrarConfirmacion("Subasta Editada");
  29.                     btncancelarActionPerformed(evt);
  30.                 } catch (Exception ex) {
  31.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  32.                 }
  33.             }            
  34.         }
  35.     }

Así tengo la parte de ediciones de las entidades:

Código Java:
Ver original
  1. public void edit(T entity) throws Exception {
  2.         if(this.checkUpdate(entity)){
  3.             ss.beginTransaction();
  4.             ss.merge(entity);
  5.             ss.getTransaction().commit();
  6.         }
  7.     }

Espero sus respuestas y saludos.
  #8 (permalink)  
Antiguo 21/04/2017, 01:09
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Creo que es un problema de la anotación OneToMany con el cascade type.

Revisa esto:

http://www.rndblog.com/hibernate-how...en-by-cascade/
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #9 (permalink)  
Antiguo 21/04/2017, 06:21
Avatar de Tipdar  
Fecha de Ingreso: octubre-2005
Ubicación: Aquí y allá.
Mensajes: 323
Antigüedad: 11 años, 8 meses
Puntos: 7
Respuesta: Guardar OneToMany Hibernate

Hola detective_jd y Fuzzylog,
Verán, en el hibernate.cfg.xml si especificamos que nos muestre en consola el código SQL que está generando Hibernate muchas veces nos ayuda a entender qué estamos haciendo mal. Intentalo:

Código XML:
Ver original
  1. <property name="show_sql">true</property>

Y si quieres formatear el código para que sea más entendible agregas:

Código XML:
Ver original
  1. <property name="format_sql">true</property>

Esto me ha tirado un cable muchas veces...
__________________
El último TipdaR
  #10 (permalink)  
Antiguo 22/04/2017, 21:04
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola Tipdar y FuzzyLog en base a lo que me dijeron me salió esto:

Hibernate:
insert
into
ventas
(estId, SuId, artId, suId)
values
(?, ?, ?, ?)
abr 22, 2017 11:57:06 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1110, SQLState: 42000
abr 22, 2017 11:57:06 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Column 'suId' specified twice
abr 22, 2017 11:57:06 PM org.hibernate.engine.jdbc.batch.internal.AbstractB atchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
abr 22, 2017 11:57:06 PM org.hibernate.internal.ExceptionMapperStandardImpl mapManagedFlushFailure
ERROR: HHH000346: Error during managed flush [org.hibernate.exception.SQLGrammarException: could not execute statement]

Con eso descubrí el gran error porque mi tabla ventas tiene 2 claves primarias que a la vez son foráneas y otra foránea y no 4.

ventas(suId,artId,estId)

pero no sé cómo rayos solucionar esto xq había visto algo sobre clase embebidas para este tipo de tablas pero ahora eso es lo que me está complicando.

Código Java:
Ver original
  1. package app.model.entity;
  2. import app.contr.util.Conversiones;
  3. import java.io.Serializable;
  4. import java.util.*;
  5. import javax.persistence.*;
  6. import up.max.proyectpages.structs.PagesList;
  7. @Table(name = "subastas")
  8. @NamedQueries({
  9.     @NamedQuery(name = "subasta.findAll",query = "select s from Subasta s"),
  10.     @NamedQuery(name = "subasta.maxId",query = "select max(s.id)+1 from Subasta s"),
  11.     @NamedQuery(name = "subasta.search",query="select s from Subasta s "
  12.             + "where s.direccion.nombre like :criterio or s.subastador.ape1 like :criterio")
  13. })
  14. public class Subasta implements Serializable
  15. {
  16.     @Id
  17.     @GeneratedValue(strategy = GenerationType.IDENTITY)
  18.     @Column(name = "suId")
  19.     private int id;
  20.     @Column(name = "suFecha")
  21.     private GregorianCalendar fecha;
  22.     @ManyToOne(cascade = CascadeType.ALL)
  23.     @JoinColumn(name = "dirId")
  24.     private Direccion direccion;
  25.     @ManyToOne(cascade = CascadeType.ALL)
  26.     @JoinColumn(name = "subId")
  27.     private Subastador subastador;
  28.     @OneToMany(mappedBy = "subasta",cascade = CascadeType.ALL)
  29.     private List<Venta>ventas;
  30.     public int getId() {
  31.         return id;
  32.     }
  33.     public void setId(int id) {
  34.         this.id = id;
  35.     }
  36.     public GregorianCalendar getFecha() {
  37.         return fecha;
  38.     }
  39.     public void setFecha(GregorianCalendar fecha) {
  40.         this.fecha = fecha;
  41.     }
  42.     public Direccion getDireccion() {
  43.         return direccion;
  44.     }
  45.     public void setDireccion(Direccion direccion) {
  46.         this.direccion = direccion;
  47.     }
  48.     public Subastador getSubastador() {
  49.         return subastador;
  50.     }
  51.     public void setSubastador(Subastador subastador) {
  52.         this.subastador = subastador;
  53.     }    
  54.     public void setVentas(List<Venta> ventas) {
  55.         this.ventas = ventas;
  56.     }
  57.     public PagesList<Venta>getVentas(){
  58.         PagesList<Venta>p = new PagesList(ventas);
  59.         return p;
  60.     }    
  61.     public void addVenta(Venta v){
  62.         ventas.add(v);
  63.     }
  64.     public void delVenta(Venta v){
  65.         ventas.remove(v);
  66.     }
  67.     public Subasta() { }
  68.     public Subasta(int id, GregorianCalendar fecha, Direccion xdireccion, Subastador xsubastador) {
  69.         this.id = id;
  70.         this.fecha = fecha;
  71.         this.direccion = xdireccion;
  72.         this.subastador = xsubastador;
  73.     }
  74.     @Override
  75.     public boolean equals(Object obj) {
  76.         if(obj instanceof Subasta){
  77.             Subasta objs = (Subasta)obj;
  78.             return objs.subastador.equals(this.subastador) && objs.fecha.equals(this.fecha);
  79.         } else {
  80.             return false;
  81.         }
  82.     }
  83.     @Override
  84.     public int hashCode() {
  85.         int hash = 17;
  86.         hash = 31 * hash + this.fecha.hashCode();
  87.         hash = 31 * hash + this.subastador.hashCode();
  88.         return hash;
  89.     }    
  90.     @Override
  91.     public String toString() {
  92.         return Conversiones.MostrarFechaYHora(fecha) + " -> " + direccion.toString();
  93.     }    
  94. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import javax.persistence.*;
  5. @Table(name = "ventas")
  6. public class Venta implements Serializable
  7. {
  8.     @EmbeddedId
  9.     private VentaKey key;
  10.     @JoinColumns({
  11.         @JoinColumn(name = "SuId",referencedColumnName = "suId"),
  12.     })
  13.     @ManyToOne(cascade = CascadeType.ALL)
  14.     private Subasta subasta;
  15.     @ManyToOne(cascade = CascadeType.ALL)
  16.     @JoinColumn(name = "estId")
  17.     private Estado obje;
  18.     @OneToMany(cascade = CascadeType.ALL, mappedBy = "venta")    
  19.     private List<Registro>registros;
  20.     public Subasta getSubasta() {
  21.         return subasta;
  22.     }
  23.     public void setSubasta(Subasta subasta) {
  24.         this.subasta = subasta;
  25.     }
  26.     public VentaKey getKey() {
  27.         return key;
  28.     }
  29.     public void setKey(VentaKey key) {
  30.         this.key = key;
  31.     }    
  32.     public Estado getObje() {
  33.         return obje;
  34.     }
  35.     public void setObje(Estado obje) {
  36.         this.obje = obje;
  37.     }
  38.     public List<Registro> getRegistros() {
  39.         return registros;
  40.     }
  41.     public void setRegistros(List<Registro> registros) {
  42.         this.registros = registros;
  43.     }    
  44.     public Venta() { }        
  45.     public Venta(Subasta xobjs, Artefacto xobja, Estado obje) {
  46.         this.key = new VentaKey(xobjs,xobja);
  47.         this.subasta = xobjs;
  48.         this.obje = obje;
  49.     }    
  50.     @Override
  51.     public boolean equals(Object obj) {
  52.         if(obj instanceof Venta){
  53.             Venta v  =(Venta)obj;
  54.             return v.key.getObja() == this.key.getObja() && v.obje.equals(this.obje);
  55.         } else {
  56.             return false;
  57.         }
  58.     }
  59.     @Override
  60.     public int hashCode() {
  61.         int hash = 17;
  62.         hash = 31 * hash + this.key.getObja().hashCode();
  63.         hash = 31 * hash + this.obje.hashCode();
  64.         return hash;
  65.     }
  66.     @Override
  67.     public String toString() {
  68.         return this.key.getObja().getNombre() + " - estado: " + this.obje.getNombre();
  69.     }  
  70. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import javax.persistence.*;
  4. @Embeddable
  5. public class VentaKey implements Serializable
  6. {
  7.     @ManyToOne(cascade = CascadeType.ALL)
  8.     @JoinColumn(name = "suId")
  9.     private Subasta subasta;
  10.     @ManyToOne(cascade = CascadeType.ALL)
  11.     @JoinColumn(name = "artId")
  12.     private Artefacto obja;
  13.     public Subasta getObjs(){
  14.         return subasta;
  15.     }
  16.     public void setObjs(Subasta objs) {
  17.         this.subasta = objs;
  18.     }
  19.     public Artefacto getObja() {
  20.         return obja;
  21.     }    
  22.     public void setObja(Artefacto obja) {
  23.         this.obja = obja;
  24.     }    
  25.     public VentaKey(){}
  26.     public VentaKey(Subasta xobjs, Artefacto xobja) {
  27.         this.subasta = xobjs;
  28.         this.obja = xobja;
  29.     }
  30.     @Override
  31.     public boolean equals(Object obj){
  32.         if(obj instanceof VentaKey){
  33.             VentaKey id =(VentaKey)obj;
  34.             return id.subasta.equals(this.subasta) && id.obja.equals(this.obja);
  35.         } else {
  36.             return false;
  37.         }
  38.     }
  39.     @Override
  40.     public int hashCode(){
  41.         int hash = 17;
  42.         hash = 31 * hash + this.subasta.hashCode();
  43.         hash = 31 * hash + this.obja.hashCode();
  44.         return hash;
  45.     }
  46. }

Lo peor de todo es que esto me hace replantear todo lo hecho hasta ahora, cómo resolverían esto??

Espero sus respuestas y Saludos.
  #11 (permalink)  
Antiguo 24/04/2017, 21:45
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola Tipdar y FuzzyLog verán descubrí gran parte de mi problema y cómo resolverlo:

En la clase Subasta tenía que borrar el atributo subasta que estaba redundante y hacer lo que puse ahora

Código Java:
Ver original
  1. @OneToMany(mappedBy = "key.subasta",cascade = CascadeType.ALL)
  2.     private List<Venta>ventas = new ArrayList();

Pero ahora estoy en que cuando guardo la subasta está queda almacenada en la base de datos, pero cuando la edito con las ventas almacenadas me da este error, cuando guardo la subasta nueva:

abr 24, 2017 11:54:51 PM org.hibernate.internal.ExceptionMapperStandardImpl mapManagedFlushFailure
ERROR: HHH000346: Error during managed flush [A different object with the same identifier value was already associated with the session : [[email protected] d078dc4]]

Cuando la edito más tarde no me da ese problema que raro ¿no?, pondré el código del botón aceptar

Código Java:
Ver original
  1. private void btnaceptarActionPerformed(java.awt.event.ActionEvent evt) {                                          
  2.         if(this.dtfecsubasta.getCalendar() == null || this.txtdirsubasta.getText().isEmpty() || this.txtsubsubasta.getText().isEmpty()){
  3.             Mensajes.MostrarAdvertencia("Ingrese los datos obligatorios (*)");
  4.         } else {
  5.             if(accion.equals("crear")){
  6.                 try {
  7.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  8.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  9.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);
  10.                     FacadeContr.getInstance().manSubastas().add(sub);                
  11.                     Mensajes.MostrarConfirmacion("Subasta Creada");
  12.                     ventana.setTitle("Editar Subasta");
  13.                     accion = "editar";
  14.                     objs = FacadeContr.getInstance().manSubastas().findById(FacadeContr.getInstance().manSubastas().maxId()-1);
  15.                 } catch (Exception ex) {
  16.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  17.                 }
  18.             } else {
  19.                 try {
  20.                     Direccion d = FacadeContr.getInstance().manDirecciones().findByX(this.txtdirsubasta.getText());
  21.                     Subastador s = FacadeContr.getInstance().manSubastadores().findByX(this.txtsubsubasta.getText());
  22.                     Subasta sub = new Subasta(Conversiones.CInt(this.txtnrosubasta.getText()), this.getDateTime(), d, s);
  23.                     sub.setVentas(objs.getVentas().toList());
  24.                     sub.getVentas().toList().forEach((v) -> {
  25.                         v.getKey().setObjs(sub);
  26.                     });
  27.                     FacadeContr.getInstance().manSubastas().edit(sub);                
  28.                     Mensajes.MostrarConfirmacion("Subasta Editada");
  29.                     btncancelarActionPerformed(evt);
  30.                 } catch (Exception ex) {
  31.                     Mensajes.MostrarAdvertencia(ex.getMessage());
  32.                 }
  33.             }            
  34.         }
  35.     }

Espero sus respuestas y Saludos.
  #12 (permalink)  
Antiguo 27/04/2017, 01:42
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Prueba con:

Cita:
@OneToMany(mappedBy = "key.subasta",cascade = CascadeType.MERGE)
private List<Venta>ventas = new ArrayList();
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #13 (permalink)  
Antiguo 27/04/2017, 18:46
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola FuzzyLog y para agregar en los OneToMany funcionó, pero ahora para borrar una venta de la subasta no sirvió, que tengo que cambiar??

Código Java:
Ver original
  1. public void delVenta(Venta v){
  2.         ventas.remove(v);
  3.     }

Espero sus respuestas y Saludos.
  #14 (permalink)  
Antiguo 28/04/2017, 01:24
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Igual el problema ahí no tiene que ver con el CascadeType

¿Te sale algo en los logs?
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #15 (permalink)  
Antiguo 02/05/2017, 21:37
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola Fuzzylog el error que me da es este:

may 03, 2017 12:37:58 AM org.hibernate.internal.ExceptionMapperStandardImpl mapManagedFlushFailure
ERROR: HHH000346: Error during managed flush [deleted object would be re-saved by cascade (remove deleted object from associations): [app.model.entity.Estado#1]]

y el pequeño cambio al código es este:

Código Java:
Ver original
  1. @OneToMany(mappedBy = "key.subasta",cascade = CascadeType.MERGE,orphanRemoval = true)
  2.     private List<Venta>ventas = new ArrayList();

Espero sus respuestas y saludos.
  #16 (permalink)  
Antiguo 03/05/2017, 02:32
Avatar de Fuzzylog  
Fecha de Ingreso: agosto-2008
Ubicación: En internet
Mensajes: 2.299
Antigüedad: 8 años, 9 meses
Puntos: 168
Respuesta: Guardar OneToMany Hibernate

Tienes que quitar antes el objeto a borrar de cualquier asociación (obj,set,list,map...) que lo tenga referenciado.
__________________
if (fuzzy && smooth) {
fuzzylog = "c00l";
return true;
}
  #17 (permalink)  
Antiguo 03/05/2017, 21:34
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola Fuzzylog Intenté lo que me djisiste y me dio este error:

ERROR: HHH000346: Error during managed flush [org.hibernate.HibernateException: identifier of an instance of app.model.entity.Venta was altered from [email protected] to null]

¿La clase del composite key no será el problema?

Código Java:
Ver original
  1. package app.model.entity;
  2. import app.contr.util.Conversiones;
  3. import java.io.Serializable;
  4. import java.util.*;
  5. import javax.persistence.*;
  6. import up.max.proyectpages.structs.PagesList;
  7. @Table(name = "subastas")
  8. ..............
  9. public class Subasta implements Serializable
  10. {
  11.     .................
  12.     @OneToMany(mappedBy = "key.subasta",cascade = CascadeType.MERGE)  
  13.     private List<Venta>ventas = new ArrayList();
  14.     .................
  15. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import javax.persistence.*;
  5. @Table(name = "ventas")
  6. public class Venta implements Serializable
  7. {
  8.     @EmbeddedId
  9.     private VentaKey key;
  10.     @ManyToOne(cascade = CascadeType.ALL)
  11.     @JoinColumn(name = "estId")
  12.     private Estado obje;
  13.     @OneToMany(cascade = CascadeType.ALL, mappedBy = "venta")    
  14.     private List<Registro>registros;
  15.     public VentaKey getKey() {
  16.         return key;
  17.     }
  18.     public void setKey(VentaKey key) {
  19.         this.key = key;
  20.     }    
  21.     public Estado getObje() {
  22.         return obje;
  23.     }
  24.     public void setObje(Estado obje) {
  25.         this.obje = obje;
  26.     }
  27.     public List<Registro> getRegistros() {
  28.         return registros;
  29.     }
  30.     public void setRegistros(List<Registro> registros) {
  31.         this.registros = registros;
  32.     }    
  33.     public Venta() { }        
  34.     public Venta(Subasta xobjs, Artefacto xobja, Estado obje) {
  35.         this.key = new VentaKey(xobjs,xobja);
  36.         this.obje = obje;
  37.     }    
  38.     @Override
  39.     public boolean equals(Object obj) {
  40.         if(obj instanceof Venta){
  41.             Venta v  =(Venta)obj;
  42.             return v.key.getObja() == this.key.getObja() && v.obje.equals(this.obje);
  43.         } else {
  44.             return false;
  45.         }
  46.     }
  47.     @Override
  48.     public int hashCode() {
  49.         int hash = 17;
  50.         hash = 31 * hash + this.key.getObja().hashCode();
  51.         hash = 31 * hash + this.obje.hashCode();
  52.         return hash;
  53.     }
  54.     @Override
  55.     public String toString() {
  56.         return this.key.getObja().getNombre() + " - estado: " + this.obje.getNombre();
  57.     }  
  58. }

Código Java:
Ver original
  1. package app.model.entity;
  2. import java.io.Serializable;
  3. import javax.persistence.*;
  4. @Embeddable
  5. public class VentaKey implements Serializable
  6. {
  7.     @ManyToOne(cascade = CascadeType.ALL)
  8.     @JoinColumn(name = "suId")
  9.     private Subasta subasta;
  10.     @ManyToOne(cascade = CascadeType.ALL)
  11.     @JoinColumn(name = "artId")
  12.     private Artefacto obja;
  13.     public Subasta getObjs(){
  14.         return subasta;
  15.     }
  16.     public void setObjs(Subasta objs) {
  17.         this.subasta = objs;
  18.     }
  19.     public Artefacto getObja() {
  20.         return obja;
  21.     }    
  22.     public void setObja(Artefacto obja) {
  23.         this.obja = obja;
  24.     }    
  25.     public VentaKey(){}
  26.     public VentaKey(Subasta xobjs, Artefacto xobja) {
  27.         this.subasta = xobjs;
  28.         this.obja = xobja;
  29.     }
  30.     @Override
  31.     public boolean equals(Object obj){
  32.         if(obj instanceof VentaKey){
  33.             VentaKey id =(VentaKey)obj;
  34.             return id.subasta.equals(this.subasta) && id.obja.equals(this.obja);
  35.         } else {
  36.             return false;
  37.         }
  38.     }
  39.     @Override
  40.     public int hashCode(){
  41.         int hash = 17;
  42.         hash = 31 * hash + this.subasta.hashCode();
  43.         hash = 31 * hash + this.obja.hashCode();
  44.         return hash;
  45.     }
  46. }

Subasta tiene una colección onetomany de ventas, pero ventas tiene una variable de tipo ventakey la cual tiene la subasta y artefacto (que son las claves primarias de la tabla ventas en mi bd) como atributo.
Que rebuscado es esto.

Espero sus respuestas y saludos.
  #18 (permalink)  
Antiguo 10/05/2017, 22:44
 
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 320
Antigüedad: 6 años, 2 meses
Puntos: 3
Respuesta: Guardar OneToMany Hibernate

Hola a todos estuve probando y viendo un poco al hacer esto:

Código Java:
Ver original
  1. public void delVenta(Venta v){
  2.         ventas.remove(v);
  3.         v.setKey(null);
  4.     }

Me da este error:

ERROR: HHH000346: Error during managed flush [org.hibernate.HibernateException: identifier of an instance of app.model.entity.Venta was altered from [email protected] to null]

pero si hago esto:

Código Java:
Ver original
  1. public void delVenta(Venta v){
  2.         v.setKey(null);
  3.         ventas.remove(v);        
  4.     }

me da este error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at app.vistas.modelos.ModeloVenta.getValueAt(ModeloVe nta.java:64)
at javax.swing.JTable.getValueAt(JTable.java:2717)
at javax.swing.JTable.prepareRenderer(JTable.java:570 6)

Sé que estoy fallando en algo, pero comienzo a pensar que los frameworks de Java me están rechazando xq con JPA no me andaba, y con hibernate que estoy intentando aprender a usarlo pasa esto.

Espero sus respuestas y saludos.



La zona horaria es GMT -6. Ahora son las 16:17.