【发布时间】:2018-02-11 21:55:24
【问题描述】:
我一直在评估将 spring-data-mongodb 用于project。总之,我的目标是:
- 使用现有的 XML 模式文件生成 Java 类。
- 这是使用JAXB xjc 实现的
- 根类为TSDProductDataType,进一步建模如下:
这里要注意的是ExtensionType 包含protected List<Object> any; 允许它存储任何类的对象。就我而言,它位于名为 TSDModule_Name_HereModuleType 的类中,可以浏览 here
-
使用 spring-data-mongodb 作为持久化存储
-
这是使用简单的ProductDataRepository 实现的
@RepositoryRestResource(collectionResourceRel = "product", path = "product") public interface ProductDataRepository extends MongoRepository<TSDProductDataType, String> { TSDProductDataType queryByGtin(@Param("gtin") String gtin); } -
然而,未编组的 TSDProductDataType 包含 spring-data-mongodb 似乎无法自行处理的 JAXBElement 并抛出 CodecConfigurationException
李>org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.lang.Class.
-
这是错误的陈述:
TSDProductDataType tsdProductDataType = jaxbElement.getValue();
repository.save(tsdProductDataType);
按照here 的解释,我尝试使用用于 spring-data-mongodb 的转换器,但是,我似乎遗漏了一些东西,因为例外是关于“编解码器”而不是“转换器”。
感谢任何帮助。
编辑:
为 JAXBElement 添加转换器
注意:适用于 org.springframework.boot::spring-boot-starter-parent 的 1.5.6.RELEASE 版本。有了 2.0.0.M3 版本,地狱就崩溃了
我在之前尝试添加转换器时似乎遗漏了一些东西。所以,我像下面这样添加它进行测试:
@Component
@ReadingConverter
public class JAXBElementReadConverter implements Converter<DBObject, JAXBElement> {
//@Autowired
//MongoConverter converter;
@Override
public JAXBElement convert(DBObject dbObject) {
Class declaredType, scope;
QName name = qNameFromString((String)dbObject.get("name"));
Object rawValue = dbObject.get("value");
try {
declaredType = Class.forName((String)dbObject.get("declaredType"));
} catch (ClassNotFoundException e) {
if (rawValue.getClass().isArray()) declaredType = List.class;
else declaredType = LinkedHashMap.class;
}
try {
scope = Class.forName((String) dbObject.get("scope"));
} catch (ClassNotFoundException e) {
scope = JAXBElement.GlobalScope.class;
}
//Object value = rawValue instanceof DBObject ? converter.read(declaredType, (DBObject) rawValue) : rawValue;
Object value = "TODO";
return new JAXBElement(name, declaredType, scope, value);
}
QName qNameFromString(String s) {
String[] parts = s.split("[{}]");
if (parts.length > 2) return new QName(parts[1], parts[2], parts[0]);
if (parts.length == 1) return new QName(parts[0]);
return new QName("undef");
}
}
@Component
@WritingConverter
public class JAXBElementWriteConverter implements Converter<JAXBElement, DBObject> {
//@Autowired
//MongoConverter converter;
@Override
public DBObject convert(JAXBElement jaxbElement) {
DBObject dbObject = new BasicDBObject();
dbObject.put("name", qNameToString(jaxbElement.getName()));
dbObject.put("declaredType", jaxbElement.getDeclaredType().getName());
dbObject.put("scope", jaxbElement.getScope().getCanonicalName());
//dbObject.put("value", converter.convertToMongoType(jaxbElement.getValue()));
dbObject.put("value", "TODO");
dbObject.put("_class", JAXBElement.class.getName());
return dbObject;
}
public String qNameToString(QName name) {
if (name.getNamespaceURI() == XMLConstants.NULL_NS_URI) return name.getLocalPart();
return name.getPrefix() + '{' + name.getNamespaceURI() + '}' + name.getLocalPart();
}
}
@SpringBootApplication
public class TsdApplication {
public static void main(String[] args) {
SpringApplication.run(TsdApplication.class, args);
}
@Bean
public CustomConversions customConversions() {
return new CustomConversions(Arrays.asList(
new JAXBElementReadConverter(),
new JAXBElementWriteConverter()
));
}
}
到目前为止一切顺利。但是,如何实例化MongoConverter converter;?
MongoConverter 是一个接口,所以我想我需要一个可实例化的类来遵守这个接口。有什么建议吗?
【问题讨论】:
标签: spring spring-boot spring-data spring-data-mongodb