当前位置: 首页 > 面试题库 >

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

苏乐童
2023-03-14
问题内容

我正在尝试将以下对象保留为spring-data-mongodbversion 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字段,而且除了添加更明确的配置外,绝对没有办法找出您实际上希望注入的字段。

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

@Document
class MyEntity {

  @Field("foo")
  private String myField;

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

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



 类似资料:
  • = 赋值操作符(在其前后没有空白符)。 不要混淆 = 与 -eq,后者用来进行比较而非赋值。 同时也要注意 = 根据使用场景既可作赋值操作符,也可作比较操作符。 样例 4-2. 变量赋值 #!/bin/bash # 非引用形式变量 echo # 什么时候变量是非引用形式,即变量名前没有 '$' 符号的呢? # 当变量在被赋值而不是被引用时。 # 赋值 a=879 echo "The value o

  • 变量名是其所指向值的一个占位符(placeholder)。引用变量值的过程我们称之为变量替换(variable substitution)。 $ 接下来我们仔细区分一下变量名与变量值。如果变量名是 variable1, 那么 $variable1 就是对变量值的引用。[^1] bash$ variable1=23 bash$ echo variable1 variable1 bash$ echo

  • 问题内容: 我有Python类,在运行时我只需要一个实例,因此每个类只具有一个属性就足够了,而每个实例只具有一次属性就足够了。如果将有多个实例(不会发生),则所有实例应具有相同的配置。我想知道以下哪种选择更好或更“惯用”的Python。 类变量: 实例变量: 问题答案: 我有Python类,在运行时我只需要一个实例,因此每个类只具有一个属性就足够了,而每个实例只具有一次属性就足够了。如果将有多个实

  • 静态变量和实例变量之间的区别是什么。下面这句话是我无法理解的: 在某些情况下,一个类的所有对象只能共享一个特定变量的副本——这里使用静态变量。 静态变量代表类范围的信息。一个类的所有对象共享相同的数据。 我认为实例变量在类范围内使用,而静态变量只在它们自己的方法中有作用域?

  • 我不明白为什么我会得到这样的错误:“prepared Statement中的变量数不匹配参数数”。 我的代码如下所示:

  • 这是唯一的解决办法吗: