Câu trả lời:
@Transient
phù hợp với nhu cầu của bạn.
Để bỏ qua một trường, chú thích nó với @Transient
nó để nó không được ánh xạ bởi chế độ ngủ đông.
nhưng sau đó jackson sẽ không tuần tự hóa trường khi chuyển đổi sang JSON.
Nếu bạn cần trộn JPA với JSON (bỏ qua JPA nhưng vẫn bao gồm trong Jackson), hãy sử dụng @JsonInclude
:
@JsonInclude()
@Transient
private String token;
TIỀN BOA:
Bạn cũng có thể sử dụng JsonInclude.Include.NON_NULL và ẩn các trường trong JSON trong quá trình giải tuần tự hóa khi token == null
:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonInclude
là không cần thiết: @Transient
các trường vẫn được bao gồm trong JSON. (Bạn vẫn nhận được phiếu bầu của tôi: kỹ thuật có thể rất hữu ích trong các trường hợp khác).
Để bỏ qua một trường, chú thích nó với @Transient
nó để nó không được ánh xạ bởi chế độ ngủ đông.
Nguồn: Chú thích ngủ đông .
Câu trả lời này đến hơi muộn, nhưng nó hoàn thành câu trả lời.
Để tránh trường từ một thực thể được duy trì trong DB, người ta có thể sử dụng một trong hai cơ chế:
@Transient - Chú thích JPA đánh dấu một trường là không bền vững
từ khóa thoáng qua trong java. Cẩn thận - sử dụng từ khóa này, sẽ ngăn trường được sử dụng với bất kỳ cơ chế tuần tự hóa nào từ java. Vì vậy, nếu trường phải được tuần tự hóa, bạn chỉ nên sử dụngchú thích @Transient .
Có nhiều giải pháp tùy thuộc vào loại thuộc tính thực thể.
Xem xét bạn có account
bảng sau :
Các account
bảng được ánh xạ tới các Account
thực thể như thế này:
@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
}
Các thuộc tính cơ bản của thực được ánh xạ vào các cột bảng, vì vậy tính chất thích id
, iban
, cents
là các thuộc tính cơ bản.
Nhưng dollars
, interestCents
và interestDollars
được tính toán tài sản, vì vậy bạn có chú thích chúng bằng @Transient
loại trừ chúng khỏi SELECT, INSERT, UPDATE, và câu lệnh SQL DELETE.
Vì vậy, đối với các thuộc tính cơ bản, bạn cần sử dụng
@Transient
để loại trừ một thuộc tính nhất định khỏi bị tồn tại.Để biết thêm chi tiết về các thuộc tính thực thể được tính toán, hãy xem bài viết này .
Giả sử bạn có những điều sau đây post
và post_comment
bảng:
Bạn muốn ánh xạ lastestComment
liên kết trong Post
thực thể đến PostComment
thực thể mới nhất đã được thêm vào.
Để làm điều đó, bạn có thể sử dụng @JoinFormula
chú thích:
@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
}
Khi tìm nạp Post
thực thể, bạn có thể thấy rằng nó latestComment
được tìm nạp, nhưng nếu bạn muốn sửa đổi nó, thay đổi sẽ bị bỏ qua.
Vì vậy, đối với các hiệp hội, bạn có thể sử dụng
@JoinFormula
để bỏ qua các hoạt động ghi trong khi vẫn cho phép đọc liên kết.Để biết thêm chi tiết về các hiệp hội tính toán, hãy xem bài viết này .
Một cách khác để bỏ qua các liên kết đã được ánh xạ bởi định danh thực thể là sử dụng @MapsId
.
Ví dụ, hãy xem xét mối quan hệ bảng một-một sau đây:
Thực PostDetails
thể được ánh xạ như thế này:
@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
}
Lưu ý rằng cả id
thuộc tính và post
liên kết ánh xạ cùng một cột cơ sở dữ liệu, đó là post_details
cột Khóa chính.
Để loại trừ id
thuộc tính, @MapsId
chú thích sẽ cho Hibernate biết rằng post
hiệp hội sẽ chăm sóc giá trị cột Chính của bảng.
Vì vậy, khi định danh thực thể và liên kết chia sẻ cùng một cột, bạn có thể sử dụng
@MapsId
để bỏ qua thuộc tính định danh thực thể và sử dụng liên kết thay thế.Để biết thêm chi tiết về
@MapsId
, hãy xem bài viết này .
insertable = false, updatable = false
Một tùy chọn khác là sử dụng insertable = false, updatable = false
cho liên kết mà bạn muốn bỏ qua bởi Hibernate.
Chẳng hạn, chúng ta có thể ánh xạ liên kết một-một trước đây như sau:
@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();
}
}
}
Các thuộc tính insertable
và updatable
thuộc tính của @JoinColumn
chú thích sẽ hướng dẫn Hibernate bỏ qua post
liên kết do định danh thực thể chăm sóc post_id
cột Khóa chính.
post
và post_details
bảng làm ví dụ không?
Không có câu trả lời nào ở trên làm việc cho tôi khi sử dụng Hibernate 5.2.10, Jersey 2.25.1 và Jackson 2.8.9. Cuối cùng tôi đã tìm thấy câu trả lời (loại, họ tham khảo hibernate4module nhưng nó cũng hoạt động cho 5) ở đây . Không có chú thích nào của Json hoạt động cả @Transient
. Rõ ràng Jackson2 đủ 'thông minh' để vui lòng bỏ qua những thứ được đánh dấu @Transient
trừ khi bạn nói rõ ràng là không. Chìa khóa là thêm mô-đun hibernate5 (mà tôi đang sử dụng để xử lý các chú thích Hibernate khác) và tắt USE_TRANSIENT_ANNOTATION
tính năng này trong Ứng dụng Jersey của tôi:
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Đây là phần phụ thuộc cho 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));
, giải pháp này cuối cùng đã có hiệu quả. Cảm ơn!