Jawaban:
@Transient
sesuai dengan kebutuhan Anda.
Untuk mengabaikan bidang, beri keterangan dengan @Transient
sehingga tidak akan dipetakan oleh hibernate.
tapi kemudian jackson tidak akan membuat cerita bersambung lapangan ketika mengkonversi ke JSON.
Jika Anda perlu mencampur JPA dengan JSON (dihilangkan oleh JPA tetapi masih termasuk dalam Jackson) gunakan @JsonInclude
:
@JsonInclude()
@Transient
private String token;
TIP:
Anda juga dapat menggunakan JsonInclude.Include.NON_NULL dan sembunyikan bidang di JSON selama deserialisasi ketika token == null
:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonInclude
itu tidak perlu: @Transient
bidang masih termasuk dalam JSON. (Anda masih mendapatkan suara saya: teknik itu sendiri mungkin sangat berguna dalam keadaan lain).
Untuk mengabaikan bidang, beri keterangan dengan @Transient
sehingga tidak akan dipetakan oleh hibernate.
Sumber: Anotasi Hibernasi .
Jawaban ini datang agak terlambat, tetapi melengkapi respons.
Untuk menghindari bidang dari entitas yang akan bertahan dalam DB seseorang dapat menggunakan salah satu dari dua mekanisme:
@Transient - anotasi JPA menandai bidang sebagai tidak dapat bertahan
kata kunci sementara di java. Hati-hati - menggunakan kata kunci ini, akan mencegah bidang untuk digunakan dengan mekanisme serialisasi apa pun dari java. Jadi, jika bidang harus serial, Anda sebaiknya menggunakananotasi @Transient saja .
Ada beberapa solusi tergantung pada tipe atribut entitas.
Pertimbangkan Anda memiliki account
tabel berikut :
The account
tabel dipetakan ke Account
entitas seperti ini:
@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
}
Atribut entitas dasar dipetakan ke kolom tabel, sehingga sifat suka id
, iban
, cents
adalah atribut dasar.
Tapi dollars
, interestCents
, dan interestDollars
yang sifat dihitung, sehingga Anda menjelaskannya dengan @Transient
mengecualikan mereka dari SELECT, INSERT, UPDATE, dan pernyataan SQL DELETE.
Jadi, untuk atribut dasar, Anda harus menggunakan
@Transient
untuk mengecualikan properti yang diberikan agar tidak tetap ada.Untuk detail lebih lanjut tentang atribut entitas yang dihitung, lihat artikel ini .
Dengan asumsi Anda memiliki yang berikut post
dan post_comment
tabel:
Anda ingin memetakan lastestComment
asosiasi di Post
entitas ke yang terbaruPostComment
entitas yang ditambahkan.
Untuk melakukannya, Anda dapat menggunakan @JoinFormula
anotasi:
@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
}
Saat mengambil Post
entitas, Anda dapat melihat bahwa latestComment
itu diambil, tetapi jika Anda ingin memodifikasinya, perubahan akan diabaikan.
Jadi, untuk asosiasi, Anda dapat menggunakan
@JoinFormula
untuk mengabaikan operasi penulisan sambil tetap membolehkan membaca asosiasi.Untuk detail lebih lanjut tentang asosiasi yang dihitung, lihat artikel ini .
Cara lain untuk mengabaikan asosiasi yang sudah dipetakan oleh pengenal entitas adalah menggunakan @MapsId
.
Misalnya, pertimbangkan hubungan tabel satu-ke-satu berikut:
The PostDetails
entitas dipetakan seperti ini:
@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
}
Perhatikan bahwa id
atribut dan post
asosiasi memetakan kolom basis data yang sama, yaitupost_details
kolom Kunci Utama.
Untuk mengecualikan id
atribut, @MapsId
anotasi akan memberi tahu Hibernate bahwa post
asosiasi menangani tabel nilai kolom Primary Key.
Jadi, ketika pengidentifikasi entitas dan asosiasi berbagi kolom yang sama, Anda bisa menggunakan
@MapsId
untuk mengabaikan atribut entitas pengidentifikasi dan menggunakan asosiasi itu.Untuk detail lebih lanjut
@MapsId
, lihat artikel ini .
insertable = false, updatable = false
Opsi lain adalah menggunakan insertable = false, updatable = false
asosiasi yang ingin Anda abaikan oleh Hibernate.
Misalnya, kita dapat memetakan asosiasi satu-ke-satu sebelumnya seperti ini:
@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();
}
}
}
The insertable
dan updatable
atribut @JoinColumn
penjelasan akan menginstruksikan Hibernate untuk mengabaikan post
asosiasi sejak entitas identifier mengurus post_id
kolom Primary Key.
post
dan post_details
tabel sebagai contoh?
Tidak ada jawaban di atas yang berfungsi untuk saya menggunakan Hibernate 5.2.10, Jersey 2.25.1 dan Jackson 2.8.9. Saya akhirnya menemukan jawabannya (semacam, mereka referensi hibernate4module tetapi berfungsi untuk 5 juga) di sini . Tak satu pun dari anotasi Json bekerja sama sekali @Transient
. Rupanya Jackson2 'cukup' cukup baik untuk mengabaikan hal-hal yang ditandai @Transient
kecuali jika Anda secara eksplisit mengatakannya untuk tidak melakukannya. Kuncinya adalah menambahkan modul hibernate5 (yang saya gunakan untuk berurusan dengan anotasi Hibernate lainnya) dan menonaktifkan USE_TRANSIENT_ANNOTATION
fitur di Aplikasi Jersey saya:
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Berikut adalah ketergantungan untuk 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));
, solusi ini akhirnya berhasil. Terima kasih!