[英]Why does reading embedded documents with Spring Data MongoDB fail if the property is typed to Object?
可以说我有以下Spring Data MongoDB接口:
public interface AccountRepository extends MongoRepository<Account, String> {}
现在,对象帐户显示在下面:
public class Account {
@Id
private String id;
private Authentication authentication; //this is from the interface org.springframework.security.core.Authentication. Here I'm using org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken which implements the interface
当我调用下面的代码时,Jackson将不会保存帐户对象,因为我没有可用于映射内部Authentication对象的Authentication模型。 此外,Jackson要求有一个Authentication()的公共空构造函数,而Spring Authentication类没有这样的构造函数:
@Autowired
AccountRepository accountRepo;
accountRepo.save(Account);
我必须将帐户模型更改为以下内容,才能将身份验证另存为对象:
public class Account {
@Id
private String id;
private Object authentication;
但是,当我尝试检索身份验证对象并将其重铸到身份验证对象时,出现此错误:
{
"timestamp": 1438441062525,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.data.mapping.model.MappingException",
"message": "No property aPrincipal found on entity class com.futureprocessing.spring.infrastructure.AuthenticatedExternalWebService to bind constructor parameter to!",
"path": "/account"
}
我总是可以将身份验证的各个部分分别保存在我的帐户对象(委托人,凭据和授予权限)中,但是如果需要的话,我将必须做一个构造函数来重新创建它。
没有简单的方法可以将身份验证对象另存为身份验证对象?
由于对象模型的更改以及先前版本使用更强的类型,数据库中已经存在的文档不包含任何类型信息。 可以理解的是,这导致Spring Data MongoDB无法推断出您想要读取嵌入式Authentication
时,它可以推断出的只是Object
类型的属性。
这里的问题是,当authentication
属性仍然是Authentication
时,数据库存储了从类模型派生的文档时,数据库不包含任何类型信息。 如果在存储时该属性的值与声明的属性具有完全相同的类型,则Spring Data MongoDB不会写入任何类型信息来避免额外的开销。
如果您使用声明为authentication
属性但包含Authentication
对象的持久化Account
,Spring Data MongoDB将向嵌入的文档中添加_class
属性以捕获类型信息,以便在读取文档时映射器知道要实例化的类型。
如果在文档中没有该附加属性,而在类型为Object
的类中没有authentication
属性,那么映射器将如何知道您在读取文档时要实例化Authentication
对象?
解决此问题的最简单方法是手动向数据库发布更新,并添加缺少的类型信息。 默认情况下,我们使用完全限定的类名,因此可以实现以下目的:
Update setTypeInformation = Update.update("authentication._class", Authentication.class.getName());
template.updateMulti(new Query(), setTypeInformation, Account.class);
Update
语句将_class
属性添加到嵌入式authentication
文档中,并将其设置为Authentication
的完全限定名称。 由于与所有现有文档匹配的空Query
,将对所有Accounts
执行Update
。
有关更多信息,请参见参考文档的相应部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.