Respostas:
A transientpalavra-chave Java é usada para indicar que um campo não deve ser serializado, enquanto a @Transientanotação do JPA é usada para indicar que um campo não deve ser persistido no banco de dados, ou seja, sua semântica é diferente.
Porque eles têm significados diferentes. A @Transientanotação informa ao provedor JPA para não persistir nenhum transientatributo (não ). O outro diz à estrutura de serialização para não serializar um atributo. Você pode querer ter uma @Transientpropriedade e ainda serializá-la.
Como já foi dito, @Transienté usado para marcar campos que não devem ser mantidos. Considere este pequeno exemplo:
public enum Gender { MALE, FEMALE, UNKNOWN }
@Entity
public Person {
private Gender g;
private long id;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public Gender getGender() { return g; }
public void setGender(Gender g) { this.g = g; }
@Transient
public boolean isMale() {
return Gender.MALE.equals(g);
}
@Transient
public boolean isFemale() {
return Gender.FEMALE.equals(g);
}
}
Quando essa classe é fornecida à JPA, ela persiste gendere idnão tenta persistir os métodos booleanos auxiliares - sem @Transiento sistema subjacente reclamará que a classe Entity Personestá ausente setMale()e com setFemale()métodos e, portanto, não persistiria Person.
O objetivo é diferente:
A transientpalavra-chave e a @Transientanotação têm dois propósitos diferentes: um lida com serialização e outro lida com persistência . Como programadores, geralmente casamos esses dois conceitos em um, mas isso não é exato em geral. Persistência refere-se à característica do estado que sobrevive ao processo que o criou. A serialização em Java refere-se ao processo de codificação / decodificação do estado de um objeto como um fluxo de bytes.
A transientpalavra-chave é uma condição mais forte do que @Transient:
Se um campo usar a transientpalavra - chave, esse campo não será serializado quando o objeto for convertido em um fluxo de bytes. Além disso, como a JPA trata os campos marcados com a transientpalavra - chave como tendo a @Transientanotação, o campo também não será mantido pela JPA.
Por outro lado, os campos anotados @Transientsozinhos serão convertidos em um fluxo de bytes quando o objeto for serializado, mas não serão mantidos pelo JPA. Portanto, a transientpalavra-chave é uma condição mais forte que a @Transientanotação.
Exemplo
Isso levanta a questão: por que alguém iria querer serializar um campo que não é persistido no banco de dados do aplicativo? A realidade é que a serialização é usada para mais do que apenas persistência . Em um aplicativo Enterprise Java, é necessário haver um mecanismo para trocar objetos entre componentes distribuídos ; a serialização fornece um protocolo de comunicação comum para lidar com isso. Assim, um campo pode conter informações críticas com a finalidade de comunicação entre componentes; mas esse mesmo campo pode não ter valor da perspectiva da persistência.
Por exemplo, suponha que um algoritmo de otimização seja executado em um servidor e suponha que esse algoritmo leve várias horas para ser concluído. Para um cliente, é importante ter o conjunto de soluções mais atualizado. Portanto, um cliente pode se inscrever no servidor e receber atualizações periódicas durante a fase de execução do algoritmo. Essas atualizações são fornecidas usando o ProgressReportobjeto:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
A Solutionclasse pode ficar assim:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
O servidor persiste cada um ProgressReportem seu banco de dados. O servidor não deseja persistir estimatedMinutesRemaining, mas o cliente certamente se preocupa com essas informações. Portanto, o estimatedMinutesRemainingé anotado usando @Transient. Quando a final Solutioné localizada pelo algoritmo, ela é persistida diretamente pela JPA sem usar a ProgressReport.
@Unpersisted,.
@Ephemeral. De acordo com Merriam Webster: Quando o efêmero foi impresso pela primeira vez em inglês nos anos 1600, "era um termo científico aplicado a febres de curto prazo e, posteriormente, a organismos (como insetos e flores) com vida útil muito curta. Logo depois disso , adquiriu um sentido estendido referente a qualquer coisa passageira e de vida curta (como em "prazeres efêmeros") ".
transientcampos como tendo implicitamente a @Transientanotação. Portanto, se você usar a transientpalavra-chave para impedir a serialização de um campo, ela também não terminará no banco de dados.
Se você deseja apenas que um campo não seja persistido, tanto o transitório quanto o @Transient funcionam. Mas a questão é por que @Transient, já que transitório já existe.
Como o campo @Transient ainda será serializado!
Suponha que você crie uma entidade, fazendo algum cálculo que consome CPU para obter um resultado e esse resultado não será salvo no banco de dados. Mas você deseja enviar a entidade para outros aplicativos Java para usar pelo JMS, então você deve usar @Transient, não a palavra-chave JavaSE transient. Assim, os receptores em execução em outras VMs podem economizar tempo para recalcular novamente.
Vou tentar responder à pergunta do "porquê". Imagine uma situação em que você tenha um enorme banco de dados com muitas colunas em uma tabela e seu projeto / sistema use ferramentas para gerar entidades do banco de dados. (O Hibernate possui esses, etc ...) Agora, suponha que, pela sua lógica de negócios, você precise de um campo específico para NÃO persistir. Você precisa "configurar" sua entidade de uma maneira específica. Embora a palavra-chave Transient funcione em um objeto - como se comporta em uma linguagem java, o @Transient projetado apenas para responder às tarefas que pertencem apenas às tarefas de persistência.