Yanıtlar:
@Transient
ihtiyaçlarınızı karşılar.
Bir alanı yok saymak için, @Transient
hazırda bekletme modu ile eşlenmeyecek şekilde ek açıklama ekleyin.
ancak jackson JSON'a dönüştürürken alanı serileştirmez .
JPA'yı JSON ile karıştırmanız gerekiyorsa (JPA tarafından atlayın, ancak yine de Jackson'a ekleyin) kullanın @JsonInclude
:
@JsonInclude()
@Transient
private String token;
İPUCU:
Ayrıca, aşağıdaki durumlarda seriyi kaldırma işlemi sırasında JsonInclude.Include.NON_NULL kullanabilir ve JSON'daki alanları gizleyebilirsiniz token == null
:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonInclude
ile gerekli değildir: @Transient
alanlar hala JSON'a dahildir. (Hala benim oyumu aldım: tekniğin kendisi diğer durumlarda çok yararlı olabilir).
Bir alanı yok saymak için, @Transient
hazırda bekletme modu ile eşlenmeyecek şekilde ek açıklama ekleyin.
Kaynak: Hazırda Bekletme Notları .
Bu cevap biraz geç gelir, ancak cevabı tamamlar.
Bir kuruluştaki bir alanın DB'de kalıcı olmasını önlemek için, iki mekanizmadan biri kullanılabilir:
@Transient - JPA ek açıklaması bir alanı kalıcı olarak işaretliyor
geçici anahtar kelime. Dikkat - bu anahtar kelimenin kullanılması, alanın java herhangi bir serileştirme mekanizması ile kullanılmasını önleyecektir. Bu nedenle, alanın serileştirilmesi gerekiyorsa, yalnızca @Transient ek açıklamasınıkullanmanız daha iyi olur.
Obje öznitelik türüne bağlı olarak birden fazla çözüm vardır.
Aşağıdaki account
tabloya sahip olduğunuzu düşünün :
account
Tablo eşleştirilir Account
böyle varlık:
@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
}
Temel varlık nitelikleri özellikleri seversin, tablo sütunları eşlenir id
, iban
, cents
temel özelliklerdir.
Ama dollars
, interestCents
ve interestDollars
sen onları açıklama yüzden, özellikler hesaplanır @Transient
SELECT, INSERT, UPDATE ve DELETE SQL ifadelerinin dışında tutmak.
Bu nedenle, temel özellikler için,
@Transient
belirli bir mülkün kalıcı olmasını engellemek için kullanmanız gerekir .Hesaplanan varlık özellikleri hakkında daha fazla bilgi için bu makaleye göz atın .
Aşağıdakilere sahip olduğunuzu varsayarsak post
ve post_comment
tablolara :
Varlıktaki lastestComment
ilişkilendirmeyi eklenen Post
en son PostComment
varlıkla eşleştirmek istiyorsunuz .
Bunu yapmak için, @JoinFormula
ek açıklamayı :
@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
}
Getirirken Post
latestComment
, getirildiğini görebilirsiniz , ancak değiştirmek isterseniz, değişiklik yok sayılır.
Böylece, ilişkilendirmeler için, ilişkilendirmeyi
@JoinFormula
okumaya izin verirken yazma işlemlerini yoksayabilirsiniz.Hesaplanan dernekler hakkında daha fazla bilgi için bu makaleye göz atın .
Varlık tanımlayıcısı tarafından önceden eşleştirilen ilişkilendirmeleri yok saymanın başka bir yolu da @MapsId
.
Örneğin, aşağıdaki bire bir tablo ilişkisini düşünün:
PostDetails
Varlık böyle eşleştirilmiş:
@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
}
Hem id
özniteliğin hem de post
ilişkilendirmenin aynı veritabanı sütununu eşlediğine dikkat edin;post_details
Birincil Anahtar sütunu eşlediğine dikkat edin.
id
Özniteliği hariç tutmak için @MapsId
ek açıklama, Hazırda Beklet'e post
ilişkilendirmenin Birincil Anahtar sütun değeri tablosuyla ilgilendiğini bildirir .
Bu nedenle, varlık tanımlayıcısı ve ilişkilendirme aynı sütunu paylaştığında
@MapsId
, varlık tanımlayıcısı niteliğini yok saymak ve bunun yerine ilişkilendirmeyi kullanabilirsiniz.Hakkında daha fazla bilgi için bu makaleye
@MapsId
göz atın .
insertable = false, updatable = false
Başka bir seçenek, insertable = false, updatable = false
Hazırda Bekletme tarafından yoksayılmasını istediğiniz ilişkilendirme için kullanmaktır .
Örneğin, önceki bire bir ilişkilendirmeyi şu şekilde eşleştirebiliriz:
@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();
}
}
}
insertable
Ve updatable
nitelikleri @JoinColumn
açıklama görmezden Hibernate talimat verir post
ilgilenir tanımlayıcı varlık beri dernek post_id
Birincil Anahtar sütununda.
post
ve post_details
tablolar bağlamında doğru mu?
Yukarıdaki cevapların hiçbiri Hibernate 5.2.10, Jersey 2.25.1 ve Jackson 2.8.9 kullanarak benim için işe yaramadı. Sonunda cevabı buldum (bir çeşit, hibernate4module'ye referans veriyorlar, ancak 5 için de çalışıyor) burada . Json ek açıklamalarının hiçbiri hiç işe yaramadı @Transient
. Görünüşe göre Jackson2, @Transient
açıkça söylemediğiniz sürece işaretlenen şeyleri göz ardı edecek kadar 'akıllı' . Anahtar, hibernate5 modülünü (diğer Hibernate ek açıklamalarıyla uğraşmak için kullandığım) eklemek ve USE_TRANSIENT_ANNOTATION
Jersey Uygulamamdaki özelliği devre dışı bırakmaktı :
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
Hibernate5Module bağımlılığı:
<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));
bu çözüm nihayet işe yaradı. Teşekkürler!