¿Por qué JPA tiene una anotación @Transient?

Resuelto deamon asked hace 14 años • 8 respuestas

Java tiene la transientpalabra clave. ¿ Por qué JPA tiene @Transienten lugar de simplemente utilizar la palabra clave java ya existente?

deamon avatar Jan 28 '10 20:01 deamon
Aceptado

La palabra clave de Java transientse usa para indicar que un campo no debe serializarse, mientras que @Transientla anotación de JPA se usa para indicar que un campo no debe persistir en la base de datos, es decir, su semántica es diferente.

Jawher avatar Jan 28 '2010 13:01 Jawher

Porque tienen diferentes significados. La @Transientanotación le dice al proveedor JPA que no persista ningún transientatributo (que no sea). El otro le dice al marco de serialización que no serialice un atributo. Es posible que desee tener una @Transientpropiedad y aun así serializarla.

Pascal Thivent avatar Jan 28 '2010 13:01 Pascal Thivent

Como han dicho otros, @Transientse utiliza para marcar campos que no deben persistir. Considere este breve ejemplo:

public enum Gender { MALE, FEMALE, UNKNOWN }

@Entity
public class 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 == g;
    }

    @Transient
    public boolean isFemale() {
        return Gender.FEMALE == g;
    }
}

Cuando esta clase se alimenta al JPA, persiste y genderpero idno intenta persistir en los métodos booleanos auxiliares; sin @Transientel sistema subyacente, se quejaría de que Personfaltan la clase Entidad setMale()y setFemale()los métodos y, por lo tanto, no persistiría Personen absoluto.

Esko avatar Jan 28 '2010 13:01 Esko

El propósito es diferente:

La transientpalabra clave y @Transientla anotación tienen dos propósitos diferentes: uno se ocupa de la serialización y el otro de la persistencia . Como programadores, a menudo unimos estos dos conceptos en uno, pero esto no es exacto en general. La persistencia se refiere a la característica del estado que sobrevive al proceso que lo creó. La serialización en Java se refiere al proceso de codificar/decodificar el estado de un objeto como un flujo de bytes.

La transientpalabra clave es una condición más fuerte que @Transient:

Si un campo usa la transientpalabra clave, ese campo no se serializará cuando el objeto se convierta en un flujo de bytes. Además, dado que JPA trata los campos marcados con la transientpalabra clave como si tuvieran la @Transientanotación, JPA tampoco conservará el campo.

Por otro lado, los campos anotados @Transientsolos se convertirán en un flujo de bytes cuando se serialice el objeto, pero JPA no los mantendrá. Por tanto, la transientpalabra clave es una condición más fuerte que la @Transientanotación.

Ejemplo

Esto plantea la pregunta: ¿Por qué alguien querría serializar un campo que no persiste en la base de datos de la aplicación? La realidad es que la serialización se utiliza para algo más que la simple 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 tanto, un campo puede contener información crítica a efectos 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 que este algoritmo tarda varias horas en completarse. Para un cliente, es importante tener el conjunto de soluciones más actualizado. Así, un cliente puede suscribirse al servidor y recibir actualizaciones periódicas durante la fase de ejecución del algoritmo. Estas actualizaciones se proporcionan utilizando el ProgressReportobjeto:

@Entity
public class ProgressReport implements Serializable{

    private static final long serialVersionUID = 1L;

    @Transient
    long estimatedMinutesRemaining;
    String statusMessage;
    Solution currentBestSolution;

}

La Solutionclase podría verse así:

@Entity
public class Solution implements Serializable{

    private static final long serialVersionUID = 1L;

    double[][] dataArray;
    Properties properties;
}

El servidor persiste cada uno ProgressReporten su base de datos. Al servidor no le importa persistir estimatedMinutesRemaining, pero al cliente ciertamente le importa esta información. Por lo tanto, se estimatedMinutesRemaininganota usando @Transient. Cuando Solutionel algoritmo localiza el final, JPA lo persiste directamente sin utilizar un archivo ProgressReport.

Austin avatar Feb 26 '2016 01:02 Austin