Olá Javeiros, estou desenvolvendo meu TC e minhas tabelas não estão ficando do modo que eu quero.
É o seguinte tenho uma classe que conterá tudo o que é comum para todas as minhas classes chamada de “BaseModel”, até então contem apenas id, e tenho todas as minha outras classes que herdam dela.
Estou mapeando da seguinte maneira:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class BaseModel implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
e como exemplo a classe Area:
@Entity
public class Area extends BaseModel {
private static final long serialVersionUID = 1L;
@Column(nullable=false, length=70)
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
O meu problema que no banco de dados esta criando a tabela BaseModel somente com id e a Area com os outros atributos.
gostaria que a classe BaseModel não gerasse uma tabala no banco, e os seus atributos fossem para a classe que herda dela.
Para não criar a tabela BaseModel, vc deve remover a anotation Entity de sua classe.
Para receber os atributos de BaseModel na sua classe área, ao invés de extender receba BaseModel como atributo na classe Área.
Veja se dessa forma funciona.
[code]public abstract class BaseModel implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
} [/code]
[code]@Entity
public class Area extends BaseModel {
private static final long serialVersionUID = 1L;
@Column(nullable=false, length=70)
private String nome;
private BaseModel base;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public BaseModel getBase() {
return base;
}
public void setBase(BaseModel base) {
this.base = base;
}
} [/code]
[quote=leonardo.bilar]Para não criar a tabela BaseModel, vc deve remover a anotation Entity de sua classe.
Para receber os atributos de BaseModel na sua classe área, ao invés de extender receba BaseModel como atributo na classe Área.
Veja se dessa forma funciona.
[code]public abstract class BaseModel implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
} [/code]
[code]@Entity
public class Area extends BaseModel {
private static final long serialVersionUID = 1L;
@Column(nullable=false, length=70)
private String nome;
private BaseModel base;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public BaseModel getBase() {
return base;
}
public void setBase(BaseModel base) {
this.base = base;
}
} [/code]
[/quote]
Testei aqui sua dica e não compila, O anotation @Entity da classe Area exije que seja definido uma key para a entidade (um id), que antes era definido da classe BaseModel.
Uma outra tentativa seria manter o @Entity em BaseModel e na classe Area receber BaseModel como atributo. Dessa forma uma tabela BaseModel sera criada.
Outra possibilidade é incluir um atributo Id na classe Area, mas já precisa verificar se atende sua necessidade.
[quote=leonardo.bilar]Uma outra tentativa seria manter o @Entity em BaseModel e na classe Area receber BaseModel como atributo. Dessa forma uma tabela BaseModel sera criada.
Outra possibilidade é incluir um atributo Id na classe Area, mas já precisa verificar se atende sua necessidade.
Acho que a segunda opcao eh a melhor![/quote]
Um isso não seria bem o que eu quiria, gostaria de utilizar todas as vantagens da OO, Assim se eu quiser adicionar um novo atributo comum a todas as classes adicionaria ali. (Por exemplo: Data de inserção e Data de Update). Eu adicionaria estes atributos somente na classe BaseModel.
irei pesquisar mais um pouco antes de desistir, mais muito obrigado pela atenção.
Você deve anotar a classe BaseModel com@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) ao invés de @Inheritance(strategy=InheritanceType.JOINED)
Se você mapeia a classe pai, a filha tem que definir qual será o campo de distinção entre elas, tanto para JOINED como SINGLE_TABLE, para a TABLE_PER_CLASS não é necessário.
Te aconselho ler, “perder 10 minutos” ao invés de ficar tentando e tomando erro e acertar sem saber por que. [=
Fiz como vc falou mais, ao iniciar o jboss ecorreu varios erros, se talves houver outra maneira ou o que aconteceu. sinão vou ter que desistir desta minha ideia.
Fiz como vc falou mais, ao iniciar o jboss ecorreu varios erros, se talves houver outra maneira ou o que aconteceu. sinão vou ter que desistir desta minha ideia.
Obrigado pela atenção.
Att. Fernando.[/quote]Mas o que ele disse está correto. Você tem que usar o TABLE_PER_CLASS.
É o único que atende ao seu requisito:[quote]gostaria que a classe BaseModel não gerasse uma tabala no banco, e os seus atributos fossem para a classe que herda dela. [/quote]
Veja o post que eu te passei, lá mostra como implementar.
[quote=Hebert Coelho]Outra coisa, TABLE_PER_CLASS é a única solução que não é “obrigação” para uma implementação de JPA (Hibernate, EclipseLink…)
As obrigações são SINGLE_TABLE e JOINED, essa é certo que funcione em todas as implementações. A TABLE_PER_CLASS ainda não é obrigatória.[/quote]
Acho que já sei o que falta para que meu mapeamento funcione como eu espero, tenho que por a classe BaseModel como abstract.
estava lendo o material que você me indicou, que é muito bom, na pagina 15 encontrei o seguinte “Caso uma entidade abstrata seja encontrada em uma hierarquia a ser persistida, essas informações serão salvas nas classes concretas abaixo dela.”
Ainda não testei pois estou no trampo e meu projeto esta no notebook, mais ao chegar em casa faço isso e teste, e posto o resultado aqui.
Testei sobre o que falei anteriormente, e o problema não era este, o correto é TABLE_PER_CLASS, para o que queria, mais não sei por que motivo não consigo fazer este tipo de mapeamento mapeando o Id da classe abstrata como @GeneratedValue(strategy = GenerationType.IDENTITY) dessa maneira não inicia o servidor jboss, se for utilizado AUTO por exemplo, o servidor inicia e cria as tabela como eu desejava, mais a estrategia de geração de ids deve ser IDENTITY no meu sistema então desisti desta herança e estou mapeando o id em cada classe.
Mais, foi muito valido o aprendizado, o artigo do uaihebert é muito bom, recomendo a todos.
[quote=descriptando.com]Testei sobre o que falei anteriormente, e o problema não era este, o correto é TABLE_PER_CLASS, para o que queria, mais não sei por que motivo não consigo fazer este tipo de mapeamento mapeando o Id da classe abstrata como @GeneratedValue(strategy = GenerationType.IDENTITY) dessa maneira não inicia o servidor jboss, se for utilizado AUTO por exemplo, o servidor inicia e cria as tabela como eu desejava, mais a estrategia de geração de ids deve ser IDENTITY no meu sistema então desisti desta herança e estou mapeando o id em cada classe.
Mais, foi muito valido o aprendizado, o artigo do uaihebert é muito bom, recomendo a todos.[/quote]Opa valeu.
OBS.: Dá uma lida sobre geração automática de ids que tem lá. São duas páginas e rápidas de ler, talvez seu problema seja detalhe bobo.