保存hibernate对象时,hibernate中是否存在设置为忽略空值的设置?
注意
在我的例子中,我通过Jackson将JSON反序列化为Hibernate Pojo。
JSON只包含Pojo的一些字段。如果我保存Pojo,那么不在JSON中的字段在Pojo中为空,而hibernate则更新它们。
我来到updateable=false
的设置,但这不是一个100%的解决方案。
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping-property
也许有人有另一个想法......
注2:
根据Hibernate文档,dynamicUpdate
注释完全相同
dynamicInsert / dynamicUpdate(默认为false):
指定应在运行时生成INSERT / UPDATE SQL 并且只包含列,其值不为空。
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-class
如果你通过dynamic-update
在XML中定义它,那么有趣的是,文档没有提到NULL值的数据。
dynamic-update(可选 - 默认为false):
指定UPDATE SQL应为>在运行时生成,只能包含值已更改的列。
由于我同时使用注释 AND xml配置,hibernate似乎忽略了我的dynamicUpdate=true
注释。
答案 0 :(得分:12)
首先应使用DB中的主键加载对象,然后在其上复制或反序列化JSON。
hibernate无法确定具有值null的属性是否已显式设置为该值,或者是否已将其排除。
如果是插入,则dynamic-insert = true应该有效。
答案 1 :(得分:0)
我已经搜索了很多关于此的内容,但对我来说没有解决方案。所以,我使用了一个不优雅的解决方案来覆盖它。
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
更改字段,然后更新对象。
答案 2 :(得分:0)
我遇到了这个问题,并且做了一个变通办法来帮助自己解决这个问题。可能有点丑陋,但可能对您也很好。如果有人觉得有调整,可以随时添加。请注意,解决方法是针对有效的实体类,并且其某些字段包含可为空的属性。这样做的好处是可以减少查询数量。
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
请注意,您可以在@JsonIgnore
字段上使用userId
之类的json批注,以在反序列化(即在生成的查询中)中将其排除。
然后,您可以使用entityManager或休眠会话运行查询。