Jawaban:
@Transient sesuai dengan kebutuhan Anda.
Untuk mengabaikan bidang, beri keterangan dengan @Transientsehingga 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;
@JsonIncludeitu tidak perlu: @Transientbidang masih termasuk dalam JSON. (Anda masih mendapatkan suara saya: teknik itu sendiri mungkin sangat berguna dalam keadaan lain).
Untuk mengabaikan bidang, beri keterangan dengan @Transientsehingga 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 accounttabel berikut :
The accounttabel dipetakan ke Accountentitas 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, centsadalah atribut dasar.
Tapi dollars, interestCents, dan interestDollarsyang sifat dihitung, sehingga Anda menjelaskannya dengan @Transientmengecualikan mereka dari SELECT, INSERT, UPDATE, dan pernyataan SQL DELETE.
Jadi, untuk atribut dasar, Anda harus menggunakan
@Transientuntuk 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 postdan post_commenttabel:
Anda ingin memetakan lastestCommentasosiasi di Postentitas ke yang terbaruPostComment entitas yang ditambahkan.
Untuk melakukannya, Anda dapat menggunakan @JoinFormulaanotasi:
@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 Postentitas, Anda dapat melihat bahwa latestCommentitu diambil, tetapi jika Anda ingin memodifikasinya, perubahan akan diabaikan.
Jadi, untuk asosiasi, Anda dapat menggunakan
@JoinFormulauntuk 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 PostDetailsentitas 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 idatribut dan postasosiasi memetakan kolom basis data yang sama, yaitupost_details kolom Kunci Utama.
Untuk mengecualikan idatribut, @MapsIdanotasi akan memberi tahu Hibernate bahwa postasosiasi menangani tabel nilai kolom Primary Key.
Jadi, ketika pengidentifikasi entitas dan asosiasi berbagi kolom yang sama, Anda bisa menggunakan
@MapsIduntuk mengabaikan atribut entitas pengidentifikasi dan menggunakan asosiasi itu.Untuk detail lebih lanjut
@MapsId, lihat artikel ini .
insertable = false, updatable = falseOpsi lain adalah menggunakan insertable = false, updatable = falseasosiasi 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 insertabledan updatableatribut @JoinColumnpenjelasan akan menginstruksikan Hibernate untuk mengabaikan postasosiasi sejak entitas identifier mengurus post_idkolom Primary Key.
postdan post_detailstabel 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 @Transientkecuali 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_ANNOTATIONfitur 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!