Mapeamento com JPA - dois relacionamento com mesma entidade

Caros,

Imaginem o cenário:

Entidade “Empresa” e entidade “Endereco”. A empresa tem duas listas de endereços (correspondencia e cobranca). A classe seria assim:

public class Empresa { private List<Endereco> correspondencias; private List<Endereco> cobrancas; private String nome; //gets e sets }

public class Endereco { // propriedades }

Preciso mapear isso com JPA e vi que a melhor forma é usando herança. Mudando as classes para:

public class Empresa { private List<EnderecoCorrespondencia> correspondencias; private List<EnderecoCobranca> cobrancas; private String nome; //gets e sets }

public class Endereco { // propriedades }

public class EnderecoCobranca extends Endereco { // propriedades }

public class EnderecoCorrespondencia extends Endereco { // propriedades }

Creio que assim resolvo o caso.

Porém vi que com Hibernate puramente, usando anotations, posso usar @Where no atributo as listas de enderecos para determinar restrições no where para cada lista de objetos. Isso é possível com JPA também?

Assim evito de usar herança desnecessariamente.

Grato

ja precisei fazer isso uma vez…
tinha desenvolvido um framework para a empresa que trabalhava que atualizava criava/atualiza uma base de dados pelo uso e interesse do usuário… e tinha que ter esse tratamento…

uma vez uma aplicação que usava esse framework precisava ter funcionalidade de envio de email e ser persistente… entao precisa de um objeto Message que tinha vários Recipient (to, cc, bcc)… entao eu tinha 3 @OneToMany para a mesma entidade…

eu lembro que consegui fazer o framework tratar esse relacionamento corretamente… eu tenho ele em casa, qdo chegar la eu poso aqui!

abraço

De qq modo, preciso disso para JPA.

Existem três maneiras de mapear este tipo de coisa usando annotations do hibernate (que tenho quase certeza, são da mesma maneira em JPA tb)

Table per Class Strategy: the element in Hibernate
Single Table per Class Hierarchy Strategy: the element in Hibernate
Joined Subclass Strategy: the element in Hibernate

De uma olhada aqui: http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#d0e788

Ignácio,
Você não entendeu a minha pergunta.
Eu sei como mapear herança com JPA e Hibernate.
A questão é, se posso fazer algo parecido com @Where do Hibernate, mas com JPA.

Estou apanhando pra botar isso para funcionar como deveria. As tabelas não existem, o próprio JPA/Hibernate cria quando inicia.

Acabei mapeando assim:

@Entity public class Empresa { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMPGEN") @SequenceGenerator(name="EMPGEN", sequenceName="EMP_SEQ", allocationSize=1) private Integer id; @OneToMany(cascade=CascadeType.ALL,mappedBy="empresa") private List<EnderecoCorrespondencia> correspondencias; @OneToMany(cascade=CascadeType.ALL,mappedBy="empresa") private List<EnderecoCobranca> cobrancas; private String nome; // gets e sets }

@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TIPO",discriminatorType=DiscriminatorType.STRING,length=1) public abstract class Endereco { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ENDGEN") @SequenceGenerator(name="ENDGEN", sequenceName="END_SEQ", allocationSize=1) private Integer id; @ManyToOne @JoinColumn(name="ID_EMPRESA") private Empresa empresa; // atributos, gets e sets }

@Entity @DiscriminatorValue("X") public class EnderecoCorrespondencia extends Endereco { // atributos, gets e sets }

@Entity @DiscriminatorValue("Y") public class EnderecoCobranca extends Endereco { // atributos, gets e sets }

Desta maneira ocorre um erro:

javax.persistence.PersistenceException: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: EnderecoCorrespondencia.empresa in Empresa.correspondencias

Curiosamente ele não acha o atributo “empresa” que pertence à classe pai Endereco.

Mudei as classes assim:

@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TIPO",discriminatorType=DiscriminatorType.STRING,length=1) public abstract class Endereco { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ENDGEN") @SequenceGenerator(name="ENDGEN", sequenceName="END_SEQ", allocationSize=1) private Integer id; // atributos, gets e sets }

[code]@Entity
@DiscriminatorValue(“X”)
public class EnderecoCorrespondencia extends Endereco {
@ManyToOne
@JoinColumn(name=“ID_EMPRESA”)
private Empresa empresa;

// atributos, gets e sets
}[/code]

[code]@Entity
@DiscriminatorValue(“Y”)
public class EnderecoCobranca extends Endereco {
@ManyToOne
@JoinColumn(name=“ID_EMPRESA”)
private Empresa empresa;

// atributos, gets e sets
}[/code]

Agora ele grava direito no BD.

Porém, quando vou buscar os dados novamente eu recebo um ClassCastException, pois ele joga os dois tipos de classe no mesmo relacionamento, ou seja, parece que ele ignora o discriminator da classe no select.

E outra, muito estranho eu ter que colocar o mesmo relacionamento com empresa nas duas classes de endereço, sendo que na super classe endereço não funciona.