如何在双向持久化 child 时级联 parent 实体

How to cascade parent entity when persisting child in bidirectional

我有一个名为 Producto 的 child class,看起来像这样:

@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

parentclass子类别如下所示:

@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

我的 child 实体 Producto 有另一个 Parent Categoria 实体,如下所示:

@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 的 Parent,如下所示:

@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 上的样子,它将 childs Producto 保存到 parent 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 注释在我的 上加载实体 Sucursal ]jsf 页面,其中我有一个属于 parent 实体 SucursalProducto 列表。我有一个保存实体 Sucursal 及其对应的 child 实体 Producto 的保存方法,我还更新了其他 parents Producto 的实体(CategoriaSubcategoria)。问题是,每当我坚持使用实体 Producto 时,它都会使用我上面提到的 Producto 列表中的最后一个 fk 进行更新。所以我的问题是如何在我的 child 实体 [=29] 上更新 SubcategoriaCategoria 的 parent fk =]Producto 每个 child 实体 Producto 属于 parent Sucursal?

您需要将 Sucursal 设为父实体。 在 Producto 实体上添加关联 SubcategoriaCategoria,然后将 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)