如何在双向持久化子级时级联父实体

时间:2016-02-08 02:20:36

标签: java hibernate jpa java-ee managed-bean

我有一个名为 Producto 的子类,如下所示:

@Entity
public class Producto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @NotNull(message = "Por favor ingrese un valor")
    private String nombre;

    @NotNull(message = "Por favor ingrese un valor")
    @Column(length = 140)
    private String descripcion;

    @NotNull(message = "Por favor ingrese un valor")
    private double precio;

    @NotNull(message = "Por favor ingrese un valor")
    private String imagen1;
    @NotNull(message = "Por favor ingrese un valor")
    private String imagen2;
    @NotNull(message = "Por favor ingrese un valor")
    private String imagen3;

    private int megusta;
    private int nomegusta;


    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "comentario_producto", referencedColumnName = "id")
    private List<Comentario> comentario = new ArrayList<Comentario>();//


    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Subcategoria subcategoria = new Subcategoria();


    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Categoria categoria = new Categoria();


    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Sucursal sucursal;


    // Getters and setters

父类子类别如下所示:

@Entity
public class Subcategoria implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @NotNull(message = "Por favor ingrese un valor")
    @Column(length = 100)
    private String nombre;

    @OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, orphanRemoval = false, mappedBy = "subcategoria")
    private List<Producto> producto = new ArrayList<Producto>();

    // getters and setters

我的子实体 Producto 有另一个父分类实体,如下所示:

@Entity
public class Categoria implements Serializable {
    @NotNull
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @NotNull(message = "Por favor ingrese un valor")
    @Column(length = 100)
    private String nombre;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "subcategoria_categoria", referencedColumnName = "id")
    private List<Subcategoria> subcategoria = new ArrayList<Subcategoria>();

    @OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, orphanRemoval = false, mappedBy = "categoria")
    private List<Producto> producto;

实体Producto有另一个名为 Sucursal 的家长,如下所示:

@Entity
public class Sucursal implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String subgerente;

    @NotNull(message = "Por favor ingrese un valor en direccion")
    @Column(length = 120)
    private String direccion;

    @NotNull(message = "Por favor ingrese un valor en telefono")
    @Column(length = 36, unique = true)
    private String telefono;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "sucursal")
    private List<Producto> producto;
//Getters and setters

这就是我的托管bean上的save方法,它将子项 Producto 保存到父 Sucursal

public void guardar() {

    List<Producto> prods = new ArrayList<Producto>();
    for (int i = 0; i < listproductos.size(); i++) {

        Producto p = new Producto();

        p.setId(listproductos.get(i).getId());
        p.setNombre(listproductos.get(i).getNombre());

        p.setDescripcion(listproductos.get(i).getDescripcion());
        p.setImagen1(listproductos.get(i).getImagen1());
        p.setImagen2(listproductos.get(i).getImagen2());
        p.setImagen3(listproductos.get(i).getImagen3());
        p.setPrecio(listproductos.get(i).getPrecio());
        p.setSucursal(newSucursal);

        p.setCategoria(categoriaDAO.read(listproductos.get(i).getCategoria().getId()));
        p.setSubcategoria(subcategoriaDAO.read(listproductos.get(i).getSubcategoria().getId()));

        prods.add(p);
        productoDAO.save(p);

    }

    newSucursal.setProductos(prods);

    sucursalDAO.save(newSucursal);

}

我的托管bean上的逻辑是我使用 @PostConstruct 注释在我的 jsf 页面上加载实体 Sucursal 属于父实体 Sucursal Producto 列表。我有一个保存方法,它将实体 Sucursal 与其相应的子实体 Producto 一起保存,我还为 Producto 的其他父项实体更新FK (分类子分类)。问题在于,无论何时我坚持实体 Producto ,都会使用上面提到的 Producto 列表中的最后一个fk进行更新。所以我的问题是如何为每个子实体 Producto <更新我的子实体 Producto 上的子类别分类的父fk / strong>属于父 Sucursal

1 个答案:

答案 0 :(得分:1)

您需要将Sucursal设为父实体。 在Subcategoria实体上添加关联CategoriaProducto,然后将Producto实体添加到Sucursal实体。

在保存新的Sucursal实体时,级联将在持久化Producto实体并添加关联时处理其余部分。

    Sucursal newSucursal = new Sucursal();
    newSucursal.setSubgerente("ABC");

    int size = 2;
    for (int i = 0; i < size; i++) {

        Producto p = new Producto();
        p.setDescripcion("Description " + i);

        //add associations
        Categoria categoria = em.find(Categoria.class, 1);
        p.setCategoria(categoria);
        Subcategoria subCategoria = em.find(Subcategoria.class, 1);
        p.setSubcategoria(subCategoria);

        //add to new sucursal
        newSucursal.addProduct(p);
    }

    sucursalDAO.save(newSucursal);

Sucursal实体

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "sucursal")
private List<Producto> producto = new ArrayList<>();

public void addProduct(Producto p) {
    p.setSucursal(this);
    this.producto.add(p);
}

上面的代码执行以下SQL语句

insert into Sucursal (id, subgerente) values (1, 'ABC')
insert into Producto (id, categoria_id, descripcion, subcategoria_id, sucursal_id) values (1, 1, 'Description 1', 1, 1)
insert into Producto (id, categoria_id, descripcion, subcategoria_id, sucursal_id) values (2, 1, 'Description 2', 1, 1)