mardi 31 mars 2015

Spring + JPA @OneToMany with orphanRemoval

I'm having a little (big) problem with Spring list form binding, and orphanRemoval. This exception occurs only when updating some item - insert and delete does work.


"A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: me.gerenciar.model.entity.PedidoItem.filhos"


Well, I have a form, and in this form, there are some items (children) that is dynamically inserted/deleted/updated on front-end with javascript.


I've made two other forms like this one, and they works perfectly, the only difference is that in this one, we have 3 hierarchy level, and the others were just 1 hierarchy level.


I know all that stuff that we can not set new dictionary like this: "this.children = children;" but this is made by Spring by reflection when binding the form entity. And as I had said, it did work on 2 other cases.


Here are my entities (without getters and setters).



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


If you guys need more details I'll immediately post it. thank you so much!




I have tried this also: http://ift.tt/1BJF9Az


no succeed =(, got null pointer exception when spring try to bind List filhos


Aucun commentaire:

Enregistrer un commentaire