Respuestas:
@Transient
Cumple con tus necesidades.
Para ignorar un campo, anótelo con @Transient
para que hibernate no lo asigne.
pero luego Jackson no serializará el campo cuando se convierta a JSON.
Si necesita mezclar JPA con JSON (omitido por JPA pero aún incluido en Jackson) use @JsonInclude
:
@JsonInclude()
@Transient
private String token;
PROPINA:
También puede usar JsonInclude.Include.NON_NULL y ocultar campos en JSON durante la deserialización cuando token == null
:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonInclude
no es necesario: los @Transient
campos todavía están incluidos en JSON. (Todavía tienes mi voto: la técnica en sí misma podría ser muy útil en otras circunstancias).
Para ignorar un campo, anótelo con @Transient
para que hibernate no lo asigne.
Fuente: Anotaciones de Hibernate .
Esta respuesta llega un poco tarde, pero completa la respuesta.
Para evitar que un campo de una entidad persista en DB, se puede usar uno de los dos mecanismos:
@Transient : la anotación JPA que marca un campo como no persistente
palabra clave transitoria en java. Cuidado: el uso de esta palabra clave evitará que el campo se use con cualquier mecanismo de serialización de java. Entonces, si el campo debe ser serializado, será mejor que use solo laanotación @Transient .
Existen múltiples soluciones según el tipo de atributo de la entidad.
Considere que tiene la siguiente account
tabla:
La account
tabla se asigna a la Account
entidad de esta manera:
@Entity(name = "Account")
public class Account {
@Id
private Long id;
@ManyToOne
private User owner;
private String iban;
private long cents;
private double interestRate;
private Timestamp createdOn;
@Transient
private double dollars;
@Transient
private long interestCents;
@Transient
private double interestDollars;
@PostLoad
private void postLoad() {
this.dollars = cents / 100D;
long months = createdOn.toLocalDateTime()
.until(LocalDateTime.now(), ChronoUnit.MONTHS);
double interestUnrounded = ( ( interestRate / 100D ) * cents * months ) / 12;
this.interestCents = BigDecimal.valueOf(interestUnrounded)
.setScale(0, BigDecimal.ROUND_HALF_EVEN).longValue();
this.interestDollars = interestCents / 100D;
}
//Getters and setters omitted for brevity
}
Los atributos básicos entidad se asignan a las columnas de las tablas, así como propiedades id
, iban
, cents
son atributos básicos.
Pero el dollars
, interestCents
y interestDollars
son propiedades computarizada, para que ellos con anotaciones @Transient
para excluirlos de SELECT, INSERT, UPDATE y DELETE sentencias SQL.
Por lo tanto, para los atributos básicos, debe usar
@Transient
para excluir una propiedad dada de ser persistente.Para obtener más detalles sobre los atributos de entidad calculados, consulte este artículo .
Suponiendo que tiene lo siguiente post
y las post_comment
tablas:
Desea asignar la lastestComment
asociación en la Post
entidad a la última PostComment
entidad que se agregó.
Para hacer eso, puedes usar la @JoinFormula
anotación:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(" +
"SELECT pc.id " +
"FROM post_comment pc " +
"WHERE pc.post_id = id " +
"ORDER BY pc.created_on DESC " +
"LIMIT 1" +
")")
private PostComment latestComment;
//Getters and setters omitted for brevity
}
Al recuperar la Post
entidad, puede ver que latestComment
se recupera, pero si desea modificarla, el cambio se ignorará.
Por lo tanto, para las asociaciones, puede usar
@JoinFormula
para ignorar las operaciones de escritura mientras todavía permite leer la asociación.Para obtener más detalles sobre las asociaciones calculadas, consulte este artículo .
Otra forma de ignorar las asociaciones que ya están asignadas por el identificador de entidad es usar @MapsId
.
Por ejemplo, considere la siguiente relación de tabla uno a uno:
La PostDetails
entidad se mapea así:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Post post;
public PostDetails() {}
public PostDetails(String createdBy) {
createdOn = new Date();
this.createdBy = createdBy;
}
//Getters and setters omitted for brevity
}
Observe que tanto el id
atributo como la post
asociación asignan la misma columna de la base de datos, que es la post_details
columna Clave primaria.
Para excluir el id
atributo, la @MapsId
anotación le indicará a Hibernate que la post
asociación se encarga del valor de la columna Clave primaria de la tabla.
Entonces, cuando el identificador de entidad y una asociación comparten la misma columna, puede usar
@MapsId
para ignorar el atributo de identificador de entidad y usar la asociación en su lugar.Para obtener más detalles al respecto
@MapsId
, consulte este artículo .
insertable = false, updatable = false
Otra opción es utilizar insertable = false, updatable = false
para la asociación que Hibernate desea ignorar.
Por ejemplo, podemos mapear la asociación individual anterior de esta manera:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
@Column(name = "post_id")
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne
@JoinColumn(name = "post_id", insertable = false, updatable = false)
private Post post;
//Getters and setters omitted for brevity
public void setPost(Post post) {
this.post = post;
if (post != null) {
this.id = post.getId();
}
}
}
Los atributos insertable
y updatable
de la @JoinColumn
anotación le indicarán a Hibernate que ignore la post
asociación, ya que el identificador de la entidad se ocupa de la post_id
columna Clave primaria.
post
y post_details
tablas como ejemplo?
Ninguna de las respuestas anteriores funcionó para mí usando Hibernate 5.2.10, Jersey 2.25.1 y Jackson 2.8.9. Finalmente encontré la respuesta (más o menos, hacen referencia a hibernate4module pero también funciona para 5) aquí . Ninguna de las anotaciones de Json funcionó en absoluto @Transient
. Al parecer, Jackson2 es lo suficientemente "inteligente" como para ignorar amablemente las cosas marcadas con, a @Transient
menos que explícitamente le digas que no lo haga. La clave era agregar el módulo hibernate5 (que estaba usando para lidiar con otras anotaciones de Hibernate) y desactivar la USE_TRANSIENT_ANNOTATION
función en mi aplicación Jersey:
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Aquí está la dependencia para el Hibernate5Module:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.8.9</version>
</dependency>
@JsonProperty
@JsonInclude
@JsonSerialize + @JsonDeserialize
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false));
esta solución finalmente funcionó. ¡Gracias!