Duda de mapeo y uso de hibernate
Hola
Estoy haciendo unos pininos con Hibernate y tengo lo siguiente
Una relacion de uno a muchos con las siguientes tablas
hib_ventas hib_det_ventas ---------------- --------------------- vnt_n_venta dvt_n_consecutivo vnt_b_fecha dvt_n_venta dvt_n_cantidad dvt_n_precio
Con el siguiente codigo
(
VNT_N_VENTA NUMBER(5,0) NOT NULL ,
VNT_D_FECHA DATE NOT NULL,
CONSTRAINT "PK_VNT" PRIMARY KEY (VNT_N_VENTA)
)
y
(
DVT_N_CONSECUTIVO NUMBER(5,0) NOT NULL,
DVT_N_PRECIO NUMBER(7,2),
DVT_N_VENTA NUMBER(5,0) NOT NULL ENABLE,
DVT_N_CANTIDAD NUMBER(5,0),
CONSTRAINT PK_DVT PRIMARY KEY (DVT_N_CONSECUTIVO)
CONSTRAINT FK_VNT FOREIGN KEY (DVT_N_VENTA) REFERENCES HIB_VENTAS (VNT_N_VENTA)
)
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Venta implements Serializable{
private static final long serialVersionUID = 1L;
private Long idVenta;
private Date fechaVenta;
private String rfcCliente;
private Set<DetalleVenta> detalleVentas;
public Venta(){
}
public Venta(Date fechaVenta, String rfcCliente,
Set<DetalleVenta> detalleVentas) {
super();
this.fechaVenta = fechaVenta;
this.rfcCliente = rfcCliente;
this.detalleVentas = detalleVentas;
}
public Long getIdVenta() {
return idVenta;
}
public void setIdVenta(Long idVenta) {
this.idVenta = idVenta;
}
public Date getFechaVenta() {
return fechaVenta;
}
public void setFechaVenta(Date fechaVenta) {
this.fechaVenta = fechaVenta;
}
public String getRfcCliente() {
return rfcCliente;
}
public void setRfcCliente(String rfcCliente) {
this.rfcCliente = rfcCliente;
}
public Set<DetalleVenta> getDetalleVentas() {
return detalleVentas;
}
public void setDetalleVentas(Set<DetalleVenta> detalleVentas) {
this.detalleVentas = detalleVentas;
}
}
import java.io.Serializable;
public class DetalleVenta implements Serializable {
private static final long serialVersionUID = 1L;
private Long consecutivo;
private Venta venta;
private Integer cantidad;
private Double precio;
public DetalleVenta(){
}
public DetalleVenta(Integer cantidad, Double precio) {
super();
this.cantidad = cantidad;
this.precio = precio;
}
public Long getConsecutivo() {
return consecutivo;
}
public void setConsecutivo(Long consecutivo) {
this.consecutivo = consecutivo;
}
public Venta getVenta() {
return venta;
}
public void setVenta(Venta venta) {
this.venta = venta;
}
public Integer getCantidad() {
return cantidad;
}
public void setCantidad(Integer cantidad) {
this.cantidad = cantidad;
}
public Double getPrecio() {
return precio;
}
public void setPrecio(Double precio) {
this.precio = precio;
}
}
venta.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="edu.tre.dominio.Venta" table="hib_ventas">
<id name="idVenta" type="java.lang.Long">
<column name="vnt_n_venta" precision="5" scale="0"/>
<generator class="native">
<param name="sequence">SEQ_VNT</param>
</generator>
</id>
<property name="fechaVenta" type="date">
<column name="vnt_d_fecha" />
</property>
<property name="rfcCliente" type="string">
<column name="vnt_s_rfc_cliente"/>
</property>
<set name="detalleVentas" table="hib_det_ventas"
inverse="true" lazy="true" fetch="select">
<key>
<column name="vnt_n_venta" />
</key>
<one-to-many class="edu.tre.dominio.DetalleVenta" />
</set>
</class>
</hibernate-mapping>
detalleVenta.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="edu.tre.dominio.DetalleVenta" table="hib_det_ventas">
<id name="consecutivo" type="java.lang.Long">
<column name="DVT_N_CONSECUTIVO" />
<generator class="native" >
<param name="sequence">SEQ_DVT</param>
</generator>
</id>
<many-to-one name="venta" class="com.scm.dominio.Venta" fetch="select">
<column name="dvt_n_venta" not-null="true" />
</many-to-one>
<property name="cantidad" type="java.lang.Integer">
<column name="dvt_n_cantidad" precision="5" />
</property>
<property name="precio" type="java.lang.Double">
<column name="dvt_n_precio" precision="7" scale="2" />
</property>
</class>
</hibernate-mapping>
Y mi app
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import edu.cfg.HibernateUtil;
import edu.tre.dominio.DetalleVenta;
import edu.tre.dominio.Venta;
public class App {
public static void main(String[] args) {
System.out.println("uno a muchos XML");
Session sesion = null;
try {
sesion = HibernateUtil.getSessionFactory().openSession();
sesion.beginTransaction();
Set<DetalleVenta> detalles = new HashSet<DetalleVenta>(0);
detalles.add(new DetalleVenta(1,1.1));
detalles.add(new DetalleVenta(2,2.2));
Venta venta = new Venta(new Date(),"Uno",detalles);
sesion.save(venta);
sesion.getTransaction().commit();
System.out.println("Finalizado");
} catch (HibernateException hE) {
sesion.getTransaction().rollback();
hE.printStackTrace();
} finally {
sesion.close();
}
}
}
Pero no me guarda los registros del detalle he visto que si pongo una tabla intermedia y hago cambios a mi mapeo puedo solucionarlo pero no creo que sea lo mas optimo.
Por otro lado puedo guardar los detalles si hago algo como
sesion.save(detalle2);
//etc...
Pero tampoco creo que sea lo mejor
Algun tip para guardar mi maestro y detalle en un solo save
- Inicie sesión o regístrese para enviar comentarios
Si haces:
Si haces:
sesion.save(detalle2);
si funciona?
Según recuerdo en hibernate las relaciones son bidireccionales, esto quiere decir que de alguna manera tienes que asegurarte que la relación entre los objetos sea en ambos lados, podrías probar algo como esto:
for(DetalleVenta detalle : detalles){ // marcamos la relacion de detalle a venta
detalle.setVenta(venta);
}
Para asegurar la relación bidireccional y ya después guardar. No sé si ese sea el problema pero igual prueba.
hbm?
Estás usando una versión muy vieja de hibernate, o por qué razón estás usando todavía el hbm? Yo la verdad prefiero configurar las entidades usando anotaciones, creo que queda mucho más claro, y sin tanto XML.
Comentarios
Jvan :
Así es, puedo poner un ciclo pero es casi lo mismo no me parece lo mejor.
Ezamudio: personalmente también prefiero las anotaciones pero estoy haciendo mis pininos antes de poner hibernate en producción y estoy familiarizandome con todo el entorno. ¿Con anotaciones resuelvo este tema de poder guardar en un solo save y sin tablas intermedias?
De antemano gracias
No es que sea lo mejor o lo
No es que sea lo mejor o lo peor, como te repito, en hibernate necesitas hacer las relaciones bidireccionales y lo puedes hacer sin for o con for pero tienes que asegurarte de hacer bidireccional la relación para que se guarden los datos consistentemente.