2015-03-31 3 views
1

У меня возникла небольшая проблема с привязкой формы списка Spring и orphanRemoval. Это исключение возникает только при обновлении некоторого элемента - вставка и удаление.Spring + JPA @OneToMany с orphanRemoval

«Коллекция с каскадом =» все-удаление-сирота «было больше не ссылается владельца экземпляра объекта: me.gerenciar.model.entity.PedidoItem.filhos»

Ну, я имеют форму, и в этой форме есть некоторые элементы (дети), которые динамически вставлены/удалены/обновлены на интерфейсе с помощью javascript.

Я создал две другие формы, подобные этой, и они отлично работают, единственное отличие состоит в том, что в этом случае у нас есть 3 уровня иерархии, а остальные - только 1 уровень иерархии.

Я знаю все, что мы не можем установить новый словарь следующим образом: "this.children = children;" но это делается весной отражением при привязке объекта формы. И, как я уже сказал, он работал над двумя другими делами.

Вот мои сущности (без геттеров и сеттеров).

//BaseEntity is just a generic way to override equals, toString and hashCode 

@Entity 
@Table(name = "PEDIDO") 
public class Pedido extends BaseEntity 
{ 
    private static final long serialVersionUID = 1586104653460442257L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID_PEDIDO") 
    private Integer pedidoId; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PESSOA_ESTABELECIMENTO") 
    private Estabelecimento estabelecimento; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PESSOA_CLIENTE") 
    private Cliente cliente; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumns({ @JoinColumn(name = "ID_MESA", referencedColumnName = "ID_MESA", insertable = false, updatable = false), @JoinColumn(name = "ID_PESSOA_ESTABELECIMENTO", referencedColumnName = "ID_PESSOA", insertable = false, updatable = false) }) 
    private Mesa mesa; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_TURNO") 
    private Turno turno; 

    @DateTimeFormat(iso = ISO.DATE_TIME) 
    @Column(name = "DATA") 
    private Date data; 

    @Column(name = "DATA", updatable = false, insertable = false) 
    private String rawData; 

    @Column(name = "PRECO") 
    private BigDecimal preco; 

    @Column(name = "FINALIZADO") 
    private Boolean finalizado; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "pedido", orphanRemoval = true) 
    @OrderBy("ID_PEDIDO_ITEM_GRUPO DESC") 
    private List<PedidoItemGrupo> pedidoItemGrupos; 

    @Column(name = "DATA_ANO") 
    private Integer dataAno; 

    @Column(name = "DATA_MES") 
    private Integer dataMes; 

    @Column(name = "DATA_DIA") 
    private Integer dataDia; 

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_CHEQUE") 
    private Cheque cheque; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) 
    @JoinTable(name = "PEDIDO_CARTAO", joinColumns = { @JoinColumn(name = "ID_PEDIDO", referencedColumnName = "ID_PEDIDO") }, inverseJoinColumns = { @JoinColumn(name = "ID_CARTAO", referencedColumnName = "ID_CARTAO") }) 
    private List<Cartao> cartoes; 

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_DINHEIRO") 
    private Dinheiro dinheiro; 

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_BOLETO") 
    private Boleto boleto; 
} 

@Entity 
@Table(name = "PEDIDO_ITEM_GRUPO") 
public class PedidoItemGrupo extends BaseEntity 
{ 
    private static final long serialVersionUID = 7785627059444833691L; 

    public static enum Tipo 
    { 
     DIVIDIDO, SOMADO 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID_PEDIDO_ITEM_GRUPO") 
    private Integer pedidoItemGrupoId; 

    @JsonIgnore 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PEDIDO") 
    private Pedido pedido; 

    @Column(name = "QUANTIDADE") 
    private BigDecimal quantidade; 

    @Column(name = "PRECO_UNITARIO") 
    private BigDecimal precoUnitario; 

    @Column(name = "PRECO") 
    private BigDecimal preco; 

    @Column(name = "DESCONTO") 
    private BigDecimal desconto; 

    @Column(name = "PRECO_FINAL") 
    private BigDecimal precoFinal; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "pedidoItemGrupo", orphanRemoval = true) 
    @Where(clause = "EXISTS (SELECT * FROM PEDIDO_ITEM WHERE ID_PEDIDO_ITEM_PAI IS NULL)") 
    private List<PedidoItem> pedidoItens; 
} 

@Entity 
@Table(name = "PEDIDO_ITEM") 
public class PedidoItem extends BaseEntity 
{ 
    private static final long serialVersionUID = 5296905009119022656L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID_PEDIDO_ITEM") 
    private Integer pedidoItemId; 

    @JsonIgnore 
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PEDIDO_ITEM_PAI") 
    private PedidoItem pai; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "pai", fetch = FetchType.EAGER, orphanRemoval = true) 
    private List<PedidoItem> filhos; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PRODUTO", insertable = false, updatable = false) 
    private Produto produto; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PRODUTO_CATEGORIA") 
    private ProdutoCategoria produtoCategoria; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumns({ @JoinColumn(name = "ID_PRODUTO", referencedColumnName = "ID_PRODUTO"), @JoinColumn(name = "TAMANHO", referencedColumnName = "TAMANHO") }) 
    private ProdutoTamanho produtoTamanho; 

    @JsonIgnore 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_PEDIDO_ITEM_GRUPO") 
    private PedidoItemGrupo pedidoItemGrupo; 

    @Column(name = "QUANTIDADE") 
    private BigDecimal quantidade; 

    @Column(name = "PRECO_UNITARIO") 
    private BigDecimal precoUnitario; 

    @Column(name = "PRECO") 
    private BigDecimal preco; 

    @Column(name = "DESCONTO") 
    private BigDecimal desconto; 

    @Column(name = "PRECO_TOTAL_UNITARIO") 
    private BigDecimal precoTotalUnitario; 

    @Column(name = "PRECO_TOTAL") 
    private BigDecimal precoTotal; 

    @Column(name = "PRECO_TOTAL_FINAL") 
    private BigDecimal precoTotalFinal; 
} 

Если вам нужны более подробные сведения, я немедленно отправлю его. большое вам спасибо!


Я попытался это также: http://mcls.github.io/blog/2012/08/07/pojo-binding-and-jpas-orphanremoval-in-play/

не получится = (, есть исключения нулевого указателя, когда пружина попытка связать Список Filhos

ответ

3

Так, им собираюсь ответить на мой собственный вопрос

.

Для вас, ребята, столкнувшись с одной и той же проблемой с привязкой POJO к спящему объекту.

Решение состоит в том, чтобы обеспечить предварительный запуск всех ваших сборов ионы, и заменить обычный метод набора для этого один

class Child { 
    private List<Child> children = new ArrayList<>(); 

    public setChildren(List<Child> children) 
    { 
     this.children.clear(); 

     if (children != null) { 
      this.children.addAll(children); 
     } 
    } 
} 

Таким образом, ты собираешься убить все другие ребенок ... Конечно, это специфический метод установки, и вы могли бы сделать общий путь с отражением , и просто «обновить» необходимых детей и «удалить» остальных.

Итак, моя последняя версия такова:

class Child extends BaseEntity { 
    private List<Child> children = new ArrayList<>(); 

    public setChildren(List<Child> children) 
    { 
     //this is the magic method, doing with Reflection on BaseEntity 
     setList(this.children, children); 
    } 
} 
Смежные вопросы