我在Spring boot 1.4.x分支和Spring Data MongoDB上。
我想从HashMap
扩展Pojo,以便动态保存新属性。
我知道我可以在Entry类中创建一个Map<String, Object>
属性来保存我的动态值,但我不想拥有内部结构。我的目标是让root的入门类中的所有字段按顺序序列化它:
{
"id":"12334234234",
"dynamicField1": "dynamicValue1",
"dynamicField2": "dynamicValue2"
}
所以我创建了这个Entry类:
@Document
public class Entry extends HashMap<String, Object> {
@Id
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
这样的存储库:
public interface EntryRepository extends MongoRepository<Entry, String> {
}
当我启动我的应用时出现此错误:
Error creating bean with name 'entryRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Could not lookup mapping metadata for domain class java.util.HashMap!
有什么想法吗?
答案 0 :(得分:10)
DBObject
与MongoTemplate
一起使用。 Spring Data Repositories repositories in the DDD sense充当您明确定义的聚合的持久性网关。他们检查域类以派生适当的查询。 Spring Data从实体分析中排除了集合和地图类型,这就是为什么从Map
扩展您的实体失败的原因。
动态属性的存储库查询方法是可能的,但它不是主要用例。您必须使用SpEL个查询来表达您的查询:
public interface EntryRepository extends MongoRepository<Entry, String> {
@Query("{ ?0 : ?1 }")
Entry findByDynamicField(String field, Object value);
}
此方法不会为您提供有关谓词值的任何类型安全性,也不会为正确的单个查询提供丑陋的别名。
而是直接使用DBObject
和MongoTemplate
及其查询方法:
List<DBObject> result = template.find(new Query(Criteria.where("your_dynamic_field")
.is(theQueryValue)), DBObject.class);
DBObject
是Map
,可让您完全访问属性,而无需强制执行预定义的结构。您可以通过Template API创建,读取,更新和删除DBObject
对象。
如果聚合根声明了一些静态属性,则可以使用Map
在嵌套级别声明动态属性:
@Document
public class Data {
@Id
private String id;
private Map<String, Object> details;
}
答案 1 :(得分:2)
这里我们可以实现使用JSONObject
实体将是这样的
@Document
public class Data {
@Id
private String id;
private JSONObject details;
//getters and setters
}
POJO将是这样的
public class DataDTO {
private String id;
private JSONObject details;
//getters and setters
}
在服务中
Data formData = new Data();
JSONObject details = dataDTO.getDetails();
details.put("dynamicField1", "dynamicValue1");
details.put("dynamicField2", "dynamicValue2");
formData.setDetails(details);
mongoTemplate.save(formData );
我按照我的业务做了,请参考此代码并将其与您的代码相关联。这有用吗?