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

标签 java naming-conventions spring-data mongodb-java 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;
    }

}

当我尝试从数据库中读回对象时,我得到了一个 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;dr

我们需要依靠构造函数参数名称来匹配字段名称,以找出要提取文档的哪个字段。如果你想自定义这个,请使用 @Value("#root.field_name") 关于构造函数参数。

说来话长

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

@Document
class MyEntity {

  @Field("foo")
  private String myField;

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

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

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

@Document
class MyEntity {

  @Field("foo")
  private String myField;

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

我强烈建议您将自定义字段名称添加到您的属性中,并且您不想将您的属性命名约定暴露给数据库。 reference docs 中简要提到了 pf @Value 的用法。但我创造了a ticket改进文档并使其更加明显。

关于java - PersistenceConstructor 参数变量名称与实例变量名称不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13832188/

相关文章:

java - Ant Ivy 依赖解析

database - 命名 "user"表的最佳做法是什么?

C 库命名约定

java - 将 ArrayList<String> 转换为字节 []

java - 如何避免使用递归调用使 executorservice 拥塞/停滞/死锁

java.io.IOException : org/at org. apache.poi.ss.usermodel.WorkbookFactory.createWorkbook(WorkbookFactory.java:326)

AngularJS - 指令名称中是否可以有下划线?

java - 如何避免Spring Data Jpa并发情况?

spring - @NamedQuery 覆盖 Spring Data Rest JpaRepository 中的 findAll

spring - hibernate logback sql