在我的Spring Boot应用程序中,我有一个像这样的实体类:
public class MyEntity {
String id;
Map<String,String> paramsMap;
//Many members omitted
}
相关的JPA ORM XML代码段是
<entity class="MyEntity" access="FIELD">
<table name="myentity">
<!--couple of unique-constraints-->
</table>
<attributes>
<element-collection name="paramsMap" fetch="EAGER">
<collection-table name="my_entity_params">
<join-column name="id" />
</collection-table>
</element-collection>
</attributes>
</entity>
这近似于this question
的答案我的问题是类MyEntity
的实体需要更新,包括params
映射的内容。发生这种情况时,Oracle DB返回一个异常,表明已违反表my_entity_params
的主键唯一约束(PostgreSQL静默地无法更新某些参数)。
更新的大概方式是:
public void updateParam(String id, String paramName, String paramValue){
MyEntity old=repository.findById(id)
old.getParamsMap().put(paramName, paramValue);
repository.save(old);
}
repository
在其中实现了接口PagingAndSortingRepository。
如果在调用paramsMap
之前未修改save
,则更新成功。我尝试先设置paramsMap
,先保存然后再保存实际地图,这会导致相同的错误。
使用one-to-many
无效,因为地图没有指向复杂的类型。同样,Eclipse Foundation Wiki的How to map collections of Basic or Emeddable values using an ElementCollection mapping文章并未阐明如何在地图上使用元素集合。
在map-key-column
下插入element-collection
元素似乎可以解决Postgres中的问题,但是当连接到Oracle数据库时问题仍然存在。
如何让Hibernate正确更新地图内容?
答案 0 :(得分:0)
看来我有两个症状相似的问题。
首先,我在map-key-column
下缺少元素element-collection
,因此Spring无法正确构造更新查询。通过更改如下元素可以解决此问题:
<element-collection name="paramsMap" fetch="EAGER">
<map-key-column name="my_entity_params_key"/>
<collection-table name="my_entity_params">
<join-column name="id" />
</collection-table>
</element-collection>
第二个问题是Oracle treats empty strings as null,这导致系统进一步混乱,并尝试在已存在键空对的情况下插入键值对。通过在插入/更新之前从映射中删除空字符串值来解决此问题。