JPA desencoraja o uso de interfaces?  XML
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Autor Mensagem
bigode_java
What is classpath?

Membro desde: 25/05/2007 19:38:04
Mensagens: 8
Offline

Olá pessoal.

Estou trabalhando em JEE. E Atualmente estou estudando JPA.
Pelo que percebi até o momento, o JPA não suporta o uso de interfaces (como um atributo persistente), em classes de entidade.

Por exemplo, desenvolvi uma interface:

e suas classes concretas. Uma dessas classes concreta é "Mobilia":

Para cada classe concreta eu tenho uma tabela mapeada no banco de dados.
Porém, eu nao sei como posso utilizar a interface "Transportavel" como um atributo persistente de uma classe de entidade.

Veja o exemplo:



Como mapear e persisti o atributo "transportavel" da classe Container ??

usar interface é uma boa prática, certo?
Um dos principios OO diz: PROGRAME PARA INTERFACE, NÃO PARA IMPLEMENTAÇÕES.

Será que o JPA não suporta mesmo o uso de interfaces (como um atributo persistente) em classes de entidade?
Tentei obter resposta a essa pergunta, mas em vão. Algumas pessoas sugeriram usar uma classe abstrata.

Mas ao meu ver seria melhor uma interface.

Assim,
Existe alguma solução?
É possivel usar interface no JPA?
victorwss
JWizard
[Avatar]

Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline

O JPA não suporta mapeamento objeto-relacional de interfaces, apenas de classes.

Existem vários problemas na implementação de baixo nível para um mapeamento assim que são difíceis de resolver. O principal destes problemas é que não existe o conceito de polimorfismo no modelo entidade-relacionamento (modelo este que é usado por quase todos os SGBDs). Desta forma, em um relacionamento entre duas tabelas, o banco de dados subjacente deve conhecer exatamente quais são as duas tabelas e elas nunca podem variar (ou seja, não é possível que em uma coluna X da tabela Y, um registro tenha a chave estrangeira apontando a tabela A e em outro registro para a tabela B), o que no lado do java significa efetivamente se amarrar a uma implementação. Para piorar este problema, entidades diferentes podem ter chaves de formatos completamente diferentes (inclusive compostas).

Existem algumas soluções parciais que atenuam este problema (mas não o eliminam). Uma delas é definir um mecanismo de herança que é mais ou menos suportado. No entanto, este mecanismo ainda tem fortes limitações. O modelo TABLE_PER_CLASS pode te induzir a ter queries gigantescas e lerdíssimas que crescem assustadoramente cada vez que você mapeia uma subclasse a mais (usam uma série de UNIONs), além de sacrificar consistência de chave estrangeira no banco de dados subjacente. O modelo SINGLE_TABLE te leva a um modelo sem normalização com o número de colunas crescendo cada vez que você cria uma subclasse, além de te impor que todos os campos das subclasses devem aceitar valores nulos. O modelo JOINED normalmente é o melhor, mas ele também pode te trazer alguns problemas e nem sempre você pode aplicá-lo. Se você fizer um select em uma lista cujo o tipo é a superclasse, vai quebrar a cara tanto com o TABLE_PER_CLASS quanto com o JOINED, pois será criada uma série de UNIONs, mas neste ponto o JOINED é um pouco melhor que o TABLE_PER_CLASS.

No entanto, ainda existem outros problemas de baixo nível além deste que eu te falei. Um destes outros problemas é que o JPA precisaria garantir que a implementação da interface, seja ela qual for, que estivesse devidamente mapeada no banco de dados para que pudesse ser persistida, coisa que na prática não é possível de garantir. A coisa mais próxima disso é a herança com JOINED.

O Hibernate tem, por fora do JPA, uma solução parcial para este problema que permite relacionar entidades com alguma outra entidade arbitrária sem que haja uma relação de herança entre essas entidades, usando as anotações @Any, @AnyMetaDef, @AnyMetaDefs e @ManyToAny, específicas do Hibernate. Nesta solução, você especifica todos os subtipos possíveis que um determinado objeto relacionado pode ter. No entanto, você tem que especificar de antemão todas as possíveis implementações, o que vai contra a ideia de se ter interfaces (aliás, nem sei se você mapeia uma interface ou se ele exige que seja simplesmente Object, mas neste caso você resolve com um simples cast). E o resultado não é dos melhores, sai algo muito parecido com o TABLE_PER_CLASS.

Resumindo: Esqueça, o que você quer fazer não é possível. A coisa mais próxima que tem é usar herança com JOINED ou TABLE_PER_CLASS, ou usar o @Any e/ou o @ManyToAny específicos do Hibernate. Ou então reestruture a sua aplicação de forma que não necessite de nenhum tipo de mapeamento de interfaces (o que normalmente é bastante doloroso).

This message was edited 12 times. Last update was at 03/03/2011 01:28:07


Victor Williams Stafusa da Silva

Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.

Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.

Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.


É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).


Se você escreve "concerteza", "concerteza" você andou matando aulas de português.
[MSN]
ivansalvadori
JavaBaby
[Avatar]

Membro desde: 04/10/2010 02:53:04
Mensagens: 93
Offline

em JPA, as entidades são POJOS, e não implementam interfaces.
bigode_java
What is classpath?

Membro desde: 25/05/2007 19:38:04
Mensagens: 8
Offline

Entendi.

Então não tem como utilizar Interface no JPA para persistir dados

Bom, tomaras que nas próximas versões do JPA seja melhorado isso, pois pelo pouco que estou mexendo deu pra perceber que o JPA é uma ótima ferramenta para persistencia a dados.

Pessoal, muito obrigado pelas respostas.
CintiaDR
JavaEvangelist
[Avatar]

Membro desde: 01/10/2007 06:49:30
Mensagens: 476
Localização: Curitiba - PR
Offline

Uma interface só pode ter atributos públicos e estáticos, não? Então, por definição (por causa do estático), uma interface nunca vai ser mapeada para o banco.

É bem diferente do caso de superclasse.

Faça Perguntas Inteligentes - NÃO me pergunte como

PelaMorDeQualquerCoisa, o GUJ não é penico! Google é seu amigo!
[MSN] [ICQ]
fabiofalci
GUJ Master
[Avatar]

Membro desde: 11/04/2006 09:23:14
Mensagens: 1057
Localização: Porto Alegre - RS
Offline

ivansalvadori wrote:em JPA, as entidades são POJOS, e não implementam interfaces.


Na verdade pode implementar interface.
Ex:
[WWW] [MSN] [ICQ]
x@ndy
Virtual Machine Man
[Avatar]

Membro desde: 07/01/2011 12:39:32
Mensagens: 554
Localização: Porto Alegre
Offline

bigode_java wrote:Entendi.

Então não tem como utilizar Interface no JPA para persistir dados

Bom, tomaras que nas próximas versões do JPA seja melhorado isso, pois pelo pouco que estou mexendo deu pra perceber que o JPA é uma ótima ferramenta para persistencia a dados.

Pessoal, muito obrigado pelas respostas.

Vale lembrar q uma "interface" pode ser uma classe abstrada tb.... de modo que se torna possível como o victorwss falou
Uma interface é uma abstração, algo que necessita ser implementado em outras classes. Programar para uma interface não necessáriamente é usar uma "interface java"

Então pode-se dizer que JPA NÃO desencoraja o uso de interfaces!

This message was edited 1 time. Last update was at 03/03/2011 14:39:08


Software e Tecnologia:http://tekhton.blogspot.com
"Um software desprovido de contexto na base do seu design é, na melhor das hipóteses, um mecanismo que realiza coisas úteis sem explicar suas ações"
[MSN]
victorwss
JWizard
[Avatar]

Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline

CintiaDR wrote:Uma interface só pode ter atributos públicos e estáticos, não? Então, por definição (por causa do estático), uma interface nunca vai ser mapeada para o banco.

É bem diferente do caso de superclasse.


Na verdade você pode mapear entidades também pelos pares de getters e setters. Não é este o motivo de não poder usar entidades mapeadas.

fabiofalci wrote:
ivansalvadori wrote:em JPA, as entidades são POJOS, e não implementam interfaces.


Na verdade pode implementar interface.
Ex:


Uma definição mais precisa seria de que apenas classes POJOs são mapeadas, o que não as proíbem de implementarem interfaces, mas as interfaces não são mapeadas.

This message was edited 1 time. Last update was at 03/03/2011 19:25:09


Victor Williams Stafusa da Silva

Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.

Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.

Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.


É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).


Se você escreve "concerteza", "concerteza" você andou matando aulas de português.
[MSN]
 
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Ir para:   
Powered by JForum 2.1.8 © JForum Team