Quando e por que as entidades JPA devem implementar a interface Serializable?

A questão está no título. Abaixo, acabei de descrever alguns dos meus pensamentos e descobertas.

Quando eu tinha um modelo de domínio muito simples (3 tabelas sem nenhuma relação), todas as minhas entidades NÃO implementavam Serializable.

Mas quando o modelo de domínio se tornou mais complexo, recebi RuntimeException, que dizia que uma das minhas entidades não implementou Serializable.

Eu uso o Hibernate como uma implementação do JPA.

Eu me pergunto:

  1. É um requisito / comportamento específico do fornecedor?
  2. O que acontece com minhas entidades serializáveis? Eles devem ser serializáveis ​​para armazenamento ou transferência?
  3. Em que momento é necessário tornar minha entidade serializável?

Isso geralmente acontece se você misturar consultas SQL e SQL nativas. No HQL, o Hibernate mapeia os tipos que você passa para o que o DB entende. Quando você executa o SQL nativo, você deve fazer o mapeamento sozinho. Se você não fizer isso, o mapeamento padrão será serializar o parâmetro e enviá-lo para o database (na esperança de que ele o entenda).

De acordo com a especificação do JPA:

Se uma instância de entidade deve ser passada por valor como um object desanexado (por exemplo, através de uma interface remota), a class de entidade deve implementar a interface Serializable.

“JSR 220: Enterprise JavaBeansTM, versão 3.0 Java Persistence API versão 3.0, versão final 2 de maio de 2006”

Você precisa que suas entidades sejam Serializable se precisar transferi-las por over-the-wire (serializá-las para outra representação), armazená-las na session http (que por sua vez é serializada no disco rígido pelo contêiner do servlet) etc.

Apenas por uma questão de persistência, Serializable não é necessário, pelo menos com o Hibernate. Mas é uma prática recomendada torná-los Serializable .

Para complementar a boa resposta de Conor, que se referiu às especificações da JSR-317. Normalmente, os projetos EAR consistem em um módulo EJB com os EJBs expostos por meio de uma interface remota. Neste caso, você precisa tornar seus beans de entidade serializáveis, pois eles são agregados no EJB remoto e são construídos para serem conectados através da rede.

Um projeto war do JEE6 sem CDI: pode conter o EJB lite respaldado por entidades JPA não serializáveis.

Um projeto de guerra do JEE6 com o CDI: Os beans que usam escopo de session, aplicativo ou conversa devem ser serializáveis, mas os beans que usam o escopo de solicitação não precisam ser serializáveis. Assim, os beans de entidade JPA subjacentes – se algum – seguiriam a mesma semântica.

Classes devem implementar Serializable se você quiser serializá-las. Isso não está diretamente relacionado ao JPA e a especificação JPA não requer que as entidades sejam serializáveis. Se o Hibernate realmente reclama sobre isso, eu suponho que seja um bug do Hibernate, mas eu suponho que você, direta ou indiretamente, esteja fazendo algo a mais com as entidades, o que requer que elas sejam serializáveis.

Eu acredito que seu problema está relacionado a ter um campo de um tipo complexo (class) que não é anotado. Nesses casos, o tratamento padrão será armazenar o object em seu formato serializado no database (o que provavelmente não é o que você pretendia fazer) Exemplo:

 Class CustomerData { int getAge(); void setAge(int age); } @Entity Class Customer { CustomerData getCustomerData(); void setCustomerData(CustomerData data) } 

No caso acima, o CustomerData será salvo em um campo de matriz de bytes no database em seu formato serializado.

De acordo com os documentos do hibernate , usando a anotação @JoinColumn:

Tem mais um parâmetro chamado referencedColumnName . Esse parâmetro declara a coluna na entidade de destino que será usada na união. Observe que ao usar referencedColumnName para uma coluna de chave não primária, a class associada deve ser Serializable .

acerto remoto usando carteiro ou ajax ou js angular etc ….., pode causar o ciclo de repetição com exceção StackOverflow com Jackson fasterxml.Assim, é melhor usar o serializador.

Este também é o erro que é lançado quando você passa um ID incorretamente typescript como o segundo param para algo como em.find () (isto é, passando a própria entidade em vez de seu ID). Eu ainda não achei necessário realmente declarar as entidades JPA serializáveis ​​- não é realmente necessário, a menos que você esteja usando referencedColumnName como descrito por man.

  1. Em que momento é necessário tornar minha entidade serializável?

A implementação de ehcache com diskstore como cache de segundo nível (ou seja, usando anotação @Cacheable em entidade ou método de serviço / repository) requer Serializable, caso contrário, o cache falhará ( NotSerializableException ) para gravar a entidade no cache de disco.