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.