繁体   English   中英

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

[英]PersistenceConstructor argument variable name doesn't match instance variable name

我试图用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;
    }

}

当我尝试从数据库中读取对象时,我得到一个MappingException (参见下面的完整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)

TL;博士

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

很长的故事

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

@Document
class MyEntity {

  @Field("foo")
  private String myField;

  public MyEntity(String myField) {
    this.myField = myField;
  }
}

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

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

@Document
class MyEntity {

  @Field("foo")
  private String myField;

  public MyEntity(@Value("#root.foo") String somethingDifferent) {
    this.myField = somethingDifferent;
  }
}

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

您可以使用一些自定义转换器(并删除@PersistenceConstructor ):

// DB => Java
package com.recorder.converters;

public class TestObjectReadConverter implements Converter<DBObject, TestObject> 
{
   public TestObject convert(final DBObject source) {
       return new TestObject((Integer) source.get("m_property"));
   }
}

// JAVA => DB
package com.recorder.converters;

public class TestObjectWriteConverter implements Converter<TestObject, DBObject> 
{
    public DBObject convert(final TestObject source) {
        return new BasicDBObjectBuilder("m_property", source.property()).get();
    }
}

不要忘记声明那些(xml配置):

<mongo:mapping-converter base-package="com.recorder">
    <mongo:custom-converters>
        <mongo:converter>
             <bean class="com.recorder.converters.TestObjectReadConverter" />
        </mongo:converter>
        <mongo:converter>
             <bean class="com.recorder.converters.TestObjectWriteConverter"/>
        </mongo:converter>
    </mongo:custom-converters>
</mongo:mapping-converter>

看到这个参考

旁注:这是一个解决方法,我不认为命名约定是如此紧密,你需要解决。 或许现在是时候让你的小组“重新思考”这些命名惯例(在这种情况下为了生产力)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM