PersistenceConstructor参数变量名称与实例变量名称不匹配

Ben*_*old 5 java naming-conventions mongodb-java spring-data spring-data-mongodb

我试图用spring-data-mongodb版本持久保存以下对象1.1.1.RELEASE:

@Document
public static class TestObject {

    private final int m_property;

    @PersistenceConstructor
    public TestObject(int a_property) {
        m_property = a_property;
    }

    public int property() {
        return m_property;
    }

}
Run Code Online (Sandbox Code Playgroud)

MappingException当我尝试从数据库中读取对象时,我得到了一个(参见下面的完整堆栈跟踪)

我的组使用的命名约定要求参数变量名称a_以及前面的实例变量名称开头m_.似乎spring-data-mongodb假设构造函数参数变量名必须与对象实例变量名匹配.

  • 为什么不spring-data-mongodb将构造函数参数用于我在构造函数中定义的实例变量映射?
  • 是否有另一种方法来定义此映射,以便spring-data-mongodb正确构造我的对象,或者是我打破命名约定的唯一选择?

.

Exception in thread "main" org.springframework.data.mapping.model.MappingException: No property a_property found on entity class com.recorder.TestRecorder$TestObject to bind constructor parameter to!
    at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:90)
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:70)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:229)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:209)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:173)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:169)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:72)
    at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:1820)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1542)
    at org.springframework.data.mongodb.core.MongoTemplate.findAll(MongoTemplate.java:1064)
    at com.recorder.TestRecorder.main(TestRecorder.java:43)
Run Code Online (Sandbox Code Playgroud)

Oli*_*ohm 17

TL;博士

我们需要依赖构造函数参数名来匹配字段名,以找出要引入的文档的哪个字段.如果要@Value("#root.field_name")在构造函数参数上自定义此用法.

很长的故事

如果你使用带有参数的构造函数让Spring Data使用这个构造函数实例化给定的类,我们必须在调用时将参数传递给构造函数.要找出我们必须提交的文档字段,我们需要检查匹配属性以进行潜在的字段名称自定义.请参阅以下示例:

@Document
class MyEntity {

  @Field("foo")
  private String myField;

  public MyEntity(String myField) {
    this.myField = myField;
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们需要将字段传递给foo构造函数,如果我们不能以某种方式获取对该属性的引用,则无法找到相关内容.如果构造函数参数名称不同,我们应该如何可靠地找出实际上应该将哪个字段值用作参数?您在问题中显示的示例永远不会开箱即用,因为您的文档将包含一个m_property字段,除了添加更明确的配置外,绝对没有办法找出您真正希望注入的字段.

要自定义此行为,您可以使用Spring的@Value注释并将自定义文档字段注入构造函数.文档本身可通过#root变量获得.因此,您可以轻松地将我的示例更改为:

@Document
class MyEntity {

  @Field("foo")
  private String myField;

  public MyEntity(@Value("#root.foo") String somethingDifferent) {
    this.myField = somethingDifferent;
  }
}
Run Code Online (Sandbox Code Playgroud)

我强烈建议您将自定义字段名称添加到属性中,并且不希望将属性命名约定公开给数据库.@Value参考文档中简要提到了用法pf ,但我创建了一个改进文档的票证并使其更加明显.