Hibernateオブジェクトを保存するときにプロパティのnull値を無視するにhibernateに設定はありますか?
[〜#〜] note [〜#〜]
私の場合、JSONをJackson経由でHibernatePojoに逆シリアル化しています。
JSONには、Pojoの一部のフィールドのみが含まれています。 Pojoを保存すると、JSONになかったフィールドはPojoでnullになり、休止状態で更新されます。
updateable=false
の設定に出くわしましたが、これは100%の解決策ではありません。 http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping-property
多分誰かが別のアイデアを持っています...
注2:
Hibernate Docsによると、dynamicUpdate
annotationはまさにそれを実行します
dynamicInsert/dynamicUpdate(デフォルトはfalse):
INSERT/UPDATE SQLを実行時に生成し、列のみを含める必要があることを指定します値がnullでない。
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-class
dynamic-update
を介してXMLで定義すると、おかしなことに、ドキュメントにはNULL値の処理については言及されていません。
動的更新(オプション-デフォルトはfalse):
UPDATE SQLは実行時に生成され、値が変更された列のみを含めることができることを指定します。
両方のアノテーションを使用しているため[〜#〜]および[〜#〜] xml構成のため、hibernateは私のdynamicUpdate=true
アノテーションを無視しているようです。
最初にDBから主キーを使用してオブジェクトをロードしてから、その上にJSONをコピーまたは逆シリアル化する必要があります。
値がnullのプロパティが明示的にその値に設定されているのか、それとも除外されているのかを休止状態で判断する方法はありません。
挿入の場合、dynamic-insert = trueが機能するはずです。
私はこれについてたくさんグーグルで検索しましたが、私にとっての解決策はありません。それで、私はそれをカバーするために優雅ではない解決策を使用しました。
public void setAccount(Account a) throws HibernateException {
try {
Account tmp = (Account) session.
get(Account.class, a.getAccountId());
tmp.setEmail(getNotNull(a.getEmail(), tmp.getEmail()));
...
tmp.setVersion(getNotNull(a.getVersion(), tmp.getVersion()));
session.beginTransaction();
session.update(tmp);
session.getTransaction().commit();
} catch (HibernateException e) {
logger.error(e.toString());
throw e;
}
}
public static <T> T getNotNull(T a, T b) {
return b != null && a != null && !a.equals(b) ? a : b;
}
多くのフィールドを含むObject a
を受け取ります。これらのフィールドはおそらくnull
ですが、mysqlに更新したくありません。 dbからtmp Obejct
を取得し、メソッドgetNotNull
でフィールドを変更してから、オブジェクトを更新します。
私はこの問題にぶつかり、これを解決するための回避策を実行しました。少し醜いかもしれませんが、あなたにとってもうまくいくかもしれません。誰かが気になったら、気軽に追加しておくとよい調整があります。回避策は、有効なエンティティクラスを対象としており、一部のフィールドにnull許容属性が含まれていることに注意してください。これの利点は、クエリの数が減ることです。
_public String getUpdateJPQL(Object obj, String column, Object value) throws JsonProcessingException, IOException {
//obj -> your entity class object
//column -> field name in the query clause
//value -> value of the field in the query clause
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(obj);
Map<String, Object> map = mapper.readValue(json, Map.class);
Map format = new HashMap();
if (value instanceof String) {
value = "'" + value + "'";
}
map.keySet()
.forEach((str) -> {
Object val = map.get(str);
if (val != null) {
format.put("t.".concat(str), "'" + val + "'");
}
});
String formatStr = format.toString();
formatStr = formatStr.substring(1, formatStr.length() - 1);
return "update " + obj.getClass()
.getSimpleName() + " t set " + formatStr + " where " + column + " = " + value + "";
}
_
例:エンティティタイプUser
のフィールド:userId
、userName
&userAge
; getUpdateJPQL(user, userId, 2)
の結果クエリは_update User t set t.userName = 'value1', t.userAge = 'value2' where t.userId = 2
_である必要があります。userId
フィールドで_@JsonIgnore
_のようなjsonアノテーションを使用して、逆シリアル化、つまり生成されたクエリで除外できることに注意してください。その後、entityManagerまたは休止状態のセッションを使用してクエリを実行できます。