2
respostas

Persistência de Abstract Column

Boa noite,

Sabemos que com JPA e Hibernate não podemos persistir uma interface, no entanto podemos substituir sua funcionalidade por uma classe abstrata apenas anotando com

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "CLASSE_NOME")
public abstract class EstadoDeUmObjeto implements Serializable 

void executar();

e suas extensões por

@DiscriminatorValue("EmDefinicao")
public class EmDefinicao extends EstadoDeUmObjeto {

void executar(){};

Assim como a interface, neste exemplo, a superclasse teria apenas um método que faria quaisquer comando.

Em uma classe de entidade é possível definir que esta superclasse seja apenas um atributo, no entanto se deixarmos as anotações da superclasse da maneira que está o hibernate criará uma nova tabela, o que não é o que queremos. Como queremos utilizar a classe abstrata como uma interface, queremos que o atributo somente armazene qual objeto está dentro do mesmo, assim definiríamos o atributo da classe como sendo

private EstadoDeUmObjeto estado = new EmDefinicao();

e na superclasse para que não seja criado a tabela deixamos apenas assim

@DiscriminatorColumn(name = "CLASSE_NOME")
public abstract class EstadoDeUmObjeto implements Serializable 

void executar();

dessa forma o Hibernate cria apenas uma coluna com tipo bytea dentro da entidade que será persistida, e além disso o seu conteúdo se exibe como "Binary Data", no entanto ao consultar com o hibernate o seu valor, o mesmo volta com o objeto do atributo "estado" correto.

A pergunta é: Se é possível identificar que o atributo consultado veio com o objeto correto, então deve existir alguma forma de armazenar esse objeto como não sendo um dado binário, e desta forma conseguimos trabalhar com as classes abstratas como se fossem interfaces. Existe alguma forma de armazenar esse objeto sem que o mesmo se apresente como dado binário? Talvez poderia se apresentar como alguma String, etc.

Obs: Existe uma anotação do hibernate @Type do pacote org.hibernate.annotations.Type que utiliza os tipos de org.hibernate.type, definindo esse tipo podemos falar para o hibernate qual tipo queremos, no entanto ao definir o tipo na coluna o JPA não entende como criar a coluna dentro do banco de dados ao se passar como String, isso devido a estar persistindo um objeto mesmo com o toString preenchido, ele também não consegue transformar em um tipo de ObjectType por erro de encapsulamento da classe TypeFactory.

2 respostas

na DiscriminatorColumn existe um atributo chamado discriminatorType que vc pode informar qual o tipo da coluna a ser criada.

Certo, existe a definição do tipo que usarei isso na superclasse, no entanto as classes que estendem da superclasse continuarão não sendo String, como defino o tipo dessas classes. Por exemplo a classe abstrata defino como string, e na classe que estende da abstrata qual anotação informo que a mesma é para ser gravado como String?

Ao gravar dessa forma, o Java apresenta ClassCastException.