2010-01-28 28 views

Respuesta

315

transient de palabras clave de Java se utiliza para denotar que un campo no es para ser serializado, mientras que @Transient anotación de JPA se utiliza para indicar que un campo no es ser persistió en la base de datos, es decir, su semántica son diferentes.

+1

Sí, la semántica es diferente. Pero, ¿por qué se diseñó JPA de esta manera? –

+1

No estoy seguro de que lo entiendo, pero eche un vistazo a la respuesta de "Pascal Thivent";) – Jawher

+18

Esto es útil porque es posible que no desee almacenar los datos en la base de datos, pero sí desea almacenarlos en el JPA Sistema de Chaching que usa la serialización para almacenar/restaurar entidades. – Kdeveloper

96

Porque tienen diferentes significados. La anotación @Transient indica al proveedor de JPA que no persista ningún atributo (no transient). El otro le dice al marco de serialización que no serialice un atributo. Es posible que desee tener una propiedad @Transient y seguir serializándola.

71

Como han dicho otros, @Transient se utiliza para marcar los campos que no deben conservarse. Considere este ejemplo corto:

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); 
    } 
} 

Cuando esta clase se alimenta a la APP, persiste la gender y id pero no trata de persistir los métodos booleanos Helper - sin @Transient el sistema subyacente se quejaba de que la clase de entidad Person falta setMale() y setFemale() métodos y por lo tanto no persistiría Person en absoluto.

+0

@psp ¿Puedes explicar más sobre por qué/cómo podría causar un comportamiento no especificado? ¡Gracias! – 40Plot

+0

@ 40Plot la especificación establece de manera – psp

+4

Esto debería ser en mi humilde opinión la respuesta aceptada, ya que es mucho más explicando que aceptaron la actual ... –

11

Si lo que desea es un campo no conseguirá persistido, tanto transitoria y @Transient trabajo. Pero la pregunta es por qué @Transient desde transient ya existe.

¡Porque el campo @Transient todavía se serializará!

Supongamos que crea una entidad, realiza un cálculo de consumo de CPU para obtener un resultado y este resultado no se guardará en la base de datos. Pero si desea enviar la entidad a otras aplicaciones Java para su uso por JMS, entonces debe usar @Transient, no la palabra clave JavaSE transient. Por lo tanto, los receptores que se ejecutan en otras VM pueden ahorrar tiempo para volver a calcular.

+0

puede que proporcione ejemplo para que sea más claro? –

0

Intentaré responder a la pregunta de "por qué". Imagina una situación en la que tienes una gran base de datos con muchas columnas en una tabla, y tu proyecto/sistema usa herramientas para generar entidades desde la base de datos. (Hibernate tiene esos, etc ...) Supongamos ahora que, según su lógica empresarial, necesita que un campo particular NO se mantenga. Tienes que "configurar" tu entidad de una manera particular. Si bien la palabra clave Transitoria funciona en un objeto, ya que se comporta dentro de un lenguaje Java, el @Transient solo se diseñó para responder las tareas que pertenecen solo a las tareas de persistencia.

26

propósito es diferente:

El transient palabra clave y @Transient anotación tienen dos propósitos diferentes: uno se ocupa de serialización y uno se ocupa de persistencia. Como programadores, a menudo combinamos estos dos conceptos en uno, pero esto no es exacto en general. Persistence se refiere a la característica del estado que sobrevive al proceso que la creó.Serialization en Java se refiere al proceso de codificación/descodificación del estado de un objeto como una secuencia de bytes.

El transient palabra clave es una condición más fuerte que @Transient:

Si un campo utiliza la palabra clave transient, ese campo no va a ser serializado cuando el objeto se convierte en un flujo de bytes. Además, dado que JPA considera que los campos marcados con la palabra clave transient tienen la anotación @Transient, tampoco JPA persistirá en el campo.

Por otro lado, los campos anotados @Transient solo voluntad ser convertido en un flujo de bytes cuando el objeto se serializa, pero no se persistió por JPA. Por lo tanto, la palabra clave transient es una condición más sólida que la anotación @Transient.

Ejemplo

Esto plantea la pregunta: ¿Por qué alguien querría para serializar un campo que no se conserva a base de datos de la aplicación? La realidad es que la serialización se usa para algo más que la persistencia. En una aplicación Enterprise Java debe haber un mecanismo para intercambiar objetos entre componentes distribuidos; la serialización proporciona un protocolo de comunicación común para manejar esto. Por lo tanto, un campo puede contener información crítica con el propósito de comunicación entre componentes; pero ese mismo campo puede no tener valor desde una perspectiva de persistencia.

Por ejemplo, supongamos que se ejecuta un algoritmo de optimización en un servidor, y supongamos que este algoritmo tarda varias horas en completarse. Para un cliente, es importante tener el conjunto de soluciones más actualizado. Entonces, un cliente puede suscribirse al servidor y recibir actualizaciones periódicas durante la fase de ejecución del algoritmo. Estas actualizaciones se proporcionan mediante el objeto ProgressReport:

@Entity 
public class ProgressReport implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    @Transient 
    long estimatedMinutesRemaining; 
    String statusMessage; 
    Solution currentBestSolution; 

} 

La clase Solution podría tener este aspecto:

@Entity 
public class Solution implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    double[][] dataArray; 
    Properties properties; 
} 

El servidor debe mantener cada ProgressReport a su base de datos. Al servidor no le importa persistir estimatedMinutesRemaining, pero el cliente ciertamente se preocupa por esta información. Por lo tanto, el estimatedMinutesRemaining se anota usando @Transient. Cuando el final Solution se encuentra por el algoritmo, es persistente por JPA directamente sin usar un ProgressReport.

+0

Si lo que realmente son diferentes preocupaciones, sin duda existe una palabra diferente que capta los matices. ¿Por qué sobrecargar el término? Como sugerencia inicial, '@ Unpersisted'. –

+1

personalmente me gusta '@ Ephemeral'. De acuerdo con Merriam Webster: Cuando efímera fue impreso por primera vez en Inglés en la década de 1600, "fue un término científico aplicado a las fiebres a corto plazo, y más tarde, a los organismos (tales como insectos y flores) con vida muy corta abarca Poco después de eso. , adquirió un sentido amplio se refiere a cualquier cosa fugaz y de corta duración (como en "placeres efímeros") ". –

+0

¡Muy buena explicación! – GOXR3PLUS

Cuestiones relacionadas