回答:
@Transient
あなたのニーズを満たします。
フィールドを無視するには、フィールドに注釈を付けて、@Transient
Hibernateによってマップされないようにします。
しかし、Jacksonは JSONへの変換時にフィールドをシリアル化しません。
JPAとJSONを混在させる必要がある場合(JPAでは省略、ただしJacksonには含まれます)を使用します@JsonInclude
。
@JsonInclude()
@Transient
private String token;
ヒント:
JsonInclude.Include.NON_NULLを使用して、逆シリアル化中にJSONのフィールドを非表示にすることもできますtoken == null
。
@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;
@JsonInclude
は必要ありません。@Transient
フィールドは引き続きJSONに含まれています。(あなたはまだ私の投票を得ました:テクニック自体は他の状況では非常に役立つかもしれません)。
フィールドを無視するには、フィールドに注釈を付けて、@Transient
Hibernateによってマップされないようにします。
出典:Hibernate Annotations。
この回答は少し遅れますが、回答は完了です。
エンティティのフィールドがDBに永続化されないようにするには、次の2つのメカニズムのいずれかを使用できます。
@Transient-フィールドを永続化できないものとしてマークするJPAアノテーション
Javaの一時的なキーワード。注意-このキーワードを使用すると、フィールドがJavaのシリアル化メカニズムで使用されなくなります。したがって、フィールドをシリアル化する必要がある場合は、 @ Transientアノテーションのみを使用することをお勧めします。
エンティティの属性タイプに応じて、複数のソリューションがあります。
次のaccount
表があるとします。
account
テーブルはにマッピングされているAccount
。このような実体:
@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
}
基本的なエンティティの属性は、プロパティが好きなので、テーブルの列にマッピングされid
、iban
、cents
基本的な属性です。
しかしdollars
、interestCents
とinterestDollars
あなたがそれらに注釈を付けるので、計算されたプロパティです@Transient
SELECT、INSERT、UPDATE、およびDELETE SQLステートメントからそれらを除外します。
したがって、基本的な属性については
@Transient
、特定のプロパティが永続化されないように除外するために使用する必要があります。計算されたエンティティ属性の詳細については、こちらの記事をご覧ください。
次のものpost
とpost_comment
テーブルがあると仮定します。
エンティティのlastestComment
関連付けをPost
最新のものにマッピングするPostComment
追加されエンティます。
これを行うには、@JoinFormula
アノテーションを使用できます。
@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
}
Post
エンティティをフェッチすると、latestComment
がフェッチされていることがわかりますが、それを変更したい場合、変更は無視されます。
したがって、関連付けの場合、を使用
@JoinFormula
して、関連付けの読み取りを許可しながら書き込み操作を無視できます。計算された関連付けの詳細については、こちらの記事をご覧ください。
エンティティ識別子によって既にマッピングされている関連付けを無視する別の方法は、を使用すること@MapsId
です。
たとえば、次の1対1のテーブルの関係を考えます。
PostDetails
エンティティは次のようにマッピングされます。
@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
}
id
属性とpost
関連付けの両方が同じデータベース列(post_details
主キー列)をマップしていることに注意してください。
id
属性を除外するために、@MapsId
アノテーションは、post
関連付けがテーブルの主キー列の値を処理することをHibernateに通知します。
したがって、エンティティ識別子と関連付けが同じ列を共有している場合は、を使用
@MapsId
してエンティティ識別子属性を無視し、代わりに関連付けを使用できます。の詳細については
@MapsId
、こちらの記事をご覧ください。
insertable = false, updatable = false
別のオプションは使用することです insertable = false, updatable = false
、Hibernateによって無視されるにする関連付けことです。
たとえば、以前の1対1の関連付けを次のようにマッピングできます。
@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
およびupdatable
属性は、関連付け@JoinColumn
を無視するようにHibernateに指示します。post
post_id
post
、post_details
表のコンテキストでは正しいですか?
Hibernate 5.2.10、Jersey 2.25.1、Jackson 2.8.9を使用した場合、上記の回答はどれもうまくいきませんでした。私は最終的に(の並べ替え、彼らはhibernate4moduleを参照するが、それはあまりにも5のために働く)答えを見つけることがここに。Jsonアノテーションはどれも、では機能しませんでした@Transient
。どうやらJackson2は、@Transient
あなたが明示的にそうしないと明示しない限り、でマークされたものを親切に無視するのに十分な「スマート」です。重要なのは、hibernate5モジュール(他のHibernateアノテーションを処理するために使用していた)を追加USE_TRANSIENT_ANNOTATION
して、Jerseyアプリケーションの機能を無効にすることでした。
ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);
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));
このソリューションは最終的に機能しました。ありがとう!