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

CREATE TABLE HIB_VENTAS
  (
    VNT_N_VENTA NUMBER(5,0) NOT NULL ,
    VNT_D_FECHA DATE NOT NULL,
 
    CONSTRAINT "PK_VNT" PRIMARY KEY (VNT_N_VENTA)
)

y

CREATE TABLE HIB_DET_VENTAS
  (
    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)
  )

package edu.tre.dominio;

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

package edu.tre.dominio;

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
<?xml version="1.0" encoding="UTF-8"?>

<!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 
<?xml version="1.0" encoding="UTF-8"?>

<!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

package com.scm.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(detalle1);
sesion.save(detalle2);
//etc...                 

Pero tampoco creo que sea lo mejor

Algun tip para guardar mi maestro y detalle en un solo save

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Jvan

Si haces:

Si haces:

sesion.save(detalle1);
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:

venta.setDetalles(detalles); //marcamos la relacion de venta a detalles

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.

Imagen de ezamudio

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

Imagen de Jvan

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.