[RESOLVIDO]Um probleminha com JPA

3 respostas
Psycopata

Gente, eu estou quebrando a cabeça com um problema de JPA.

Bom, o meu domínio é o seguinte:

[Cliente] 1----------N [Produto]N----------1[Venda]
     |                                        |
     1----------------------------------------N

Ok, o meu mapeamento de entidades ficou assim:

Entidade Cliente:

@Entity
@Table(name = "cliente")
@NamedQuery ( name="todosClientes", query="SELECT c FROM Cliente c")
public class Cliente implements Serializable
{

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String nome;

    @OneToMany(mappedBy = "id")
    private List<Produto> produto;

    @OneToMany(mappedBy = "id")
    private List<Venda> venda;

Entidade Venda:

@Entity
@Table(name="venda")
@NamedQuery(name="vendasDeClientes", query="SELECT v FROM Venda WHERE v.cliente.id = :identificador")
public class Venda implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy="id")
    private List<Produto> produto;

    @ManyToOne
    @JoinColumn(name="id", referencedColumnName="id")
    private Cliente cliente;
    
    @Column
    private Integer quantidade;

    @Column
    private Long valor;

Entidade Produto:

@Entity
@Table(name="produto")
public class Produto implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String nome;

    @ManyToOne
    @JoinColumn(name="id", referencedColumnName="id")
    private Cliente cliente;

    @ManyToOne
    @JoinColumn(name="id", referencedColumnName="id")
    private Venda venda;

Ok, mas quando eu rodo, é lançado o seguinte erro:

Exception [EclipseLink-7244] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.ValidationException
Exception Description: An incompatible mapping has been encountered between [class entidades.Cliente] and [class entidades.Produto]. This usually occurs when the cardinality of a mapping does not correspond with the cardinality of its backpointer.
	org.eclipse.persistence.exceptions.ValidationException.invalidMapping(ValidationException.java:1235)

O que pode está acontecendo? Porque o EclipseLink não está aceitando o relacionamento?

3 Respostas

guedes

Olá Psycopata,

evite colar as classes inteiras no tópico.
Fica muito extenso e ruim de ler, desmotiva as pessoas a quererem te ajudar.
Copie apenas os trechos pertinentes ao problema, no seu caso apenas a declaração das classes e os atributos já seriam suficiente.

Em relação ao mapeamento, não entendi o mapeamento do cliente com o produto.
A meu ver o cliente só terias o relacionamento com Venda, e ai sim Venda teria os Produtos que o Cliente comprou.

Pensando de um jeito um pouco diferente, o cliente só pode ter os produtos se antes existir uma venda.

Psycopata

Eu vou editar então.

Bom, isso é um exercício. Eu pensei em refazer o relacionamento. Mas ai eu pensei que, mesmo da forma que está, era para funcionar.

Tá, a idéia era que a pessoa que vende, também compra. Por isso é que a entidade é Venda e não compra.

Mas isso só é detalhe. Eu vou refazer esse relacionamento e deixar [Cliente] 1----- N [Venda] 1 ----- N [Produto]

Psycopata

Descobri o problema: nas entidades que possuem a anotação @OneToMany, o parâmetro MappedBy mapeia a propriedade da outra entidade do relacionamento. Eu estava indicando o nome do campo da tabela do banco de dados.

então fica assim:

Ao invés disso:

@Entity  
@Table(name = "cliente")  
@NamedQuery ( name="todosClientes", query="SELECT c FROM Cliente c")  
public class Cliente implements Serializable  
{  
  
    private static final long serialVersionUID = 1L;  
    @Id  
    @GeneratedValue(strategy = GenerationType.AUTO)  
    private Long id;  
  
    @Column  
    private String nome;  
  
    @OneToMany(mappedBy = "id")  
    private List<Produto> produto;  
  
    @OneToMany(mappedBy = "id")  
    private List<Venda> venda;

Devo usar isso:

@Entity  
@Table(name = "cliente")  
@NamedQuery ( name="todosClientes", query="SELECT c FROM Cliente c")  
public class Cliente implements Serializable  
{  
  
    private static final long serialVersionUID = 1L;  
    @Id  
    @GeneratedValue(strategy = GenerationType.AUTO)  
    private Long id;  
  
    @Column  
    private String nome;  
  
    @OneToMany(mappedBy = "cliente")  
    private List<Produto> produto;  
  
    @OneToMany(mappedBy = "cliente")  
    private List<Venda> venda;

Porque nas classes Produto e Venda, o atributo cliente é que faz a ligação do relacionamento, e não o ID de Cliente, como eu tinha colocado.

Criado 15 de fevereiro de 2010
Ultima resposta 16 de fev. de 2010
Respostas 3
Participantes 2