Respuestas:
@Transient Cumple con tus necesidades.
Para ignorar un campo, anótelo con @Transientpara 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;
@JsonIncludeno es necesario: los @Transientcampos 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 @Transientpara 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 accounttabla:
La accounttabla se asigna a la Accountentidad 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, centsson atributos básicos.
Pero el dollars, interestCentsy interestDollarsson propiedades computarizada, para que ellos con anotaciones @Transientpara excluirlos de SELECT, INSERT, UPDATE y DELETE sentencias SQL.
Por lo tanto, para los atributos básicos, debe usar
@Transientpara 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 posty las post_commenttablas:
Desea asignar la lastestCommentasociación en la Postentidad a la última PostCommententidad que se agregó.
Para hacer eso, puedes usar la @JoinFormulaanotació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 Postentidad, puede ver que latestCommentse recupera, pero si desea modificarla, el cambio se ignorará.
Por lo tanto, para las asociaciones, puede usar
@JoinFormulapara 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 PostDetailsentidad 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 idatributo como la postasociación asignan la misma columna de la base de datos, que es la post_detailscolumna Clave primaria.
Para excluir el idatributo, la @MapsIdanotación le indicará a Hibernate que la postasociació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
@MapsIdpara 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 = falseOtra opción es utilizar insertable = false, updatable = falsepara 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 insertabley updatablede la @JoinColumnanotación le indicarán a Hibernate que ignore la postasociación, ya que el identificador de la entidad se ocupa de la post_idcolumna Clave primaria.
posty post_detailstablas 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 @Transientmenos 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_ANNOTATIONfunció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!