我不确定Morphia的设计方式是否正确,但在这里......
Student.class(省略方法)
@Entity(value = "students", noClassnameStored = true)
public class Student
{
@Id
private String id = new ObjectId().toString();
private String name;
private String city = "London"; // Default Value
}
注意:我已将 DEFAULT 值分配给实例变量city
。
现在代码......
Student s1 = new Student("James Bond"); // London IS his default city
ds.save(s1);
Student s2 = new Student("Jason Bourne");
s2.setCity("New York"); // Set a city for Mr. Bourne
ds.save(s2);
System.out.println("----- Normal -----");
List<Student> studentsNormal = ds.createQuery(Student.class).asList();
for(Student s: studentsNormal)
System.out.println(s);
System.out.println("----- Projected -----");
Query<Student> query = ds.find(Student.class);
query.retrievedFields(false, "city");
List<Student> studentsProjected = query.asList();
for(Student s: studentsProjected)
System.out.println(s);
现在输出......
----- Normal -----
Student{id='57337553db4f0f0f10a93941', name='James Bond', city='London'}
Student{id='57337553db4f0f0f10a93942', name='Jason Bourne', city='New York'}
----- Projected -----
Student{id='57337553db4f0f0f10a93941', name='James Bond', city='London'}
Student{id='57337553db4f0f0f10a93942', name='Jason Bourne', city='London'}
现在,关于Morphia行为的4个问题......
Q1。对于Bond先生,我没有更改city
并从投影列表中排除city
,但city
的默认值打印为London
。这不应该是空的吗?
Q2。对于Bourne先生,我确实将city
更改为New York
但仍然在投影期间,它选择了默认值并显示London
。这也不应该是空的吗?
我还没有看过Morphia的Projection.class(打算今晚这样做),但似乎对于排除,Morphia似乎拿起默认值并且不会覆盖{ {1}}。现在这成了一个障碍因为我没有办法为我的实例变量提供默认值而不将它们暴露给客户端......
Q3。这是Morphia还是MongoD Java Driver行为/问题?
最后一个问题......
Q4。任何已知的解决方法吗?
我已经google了一下,但到目前为止还没有任何解决方案或解释......
提前致谢...
SG
答案 0 :(得分:2)
当Morphia从查询结果中读取您的文档时,它首先要做的是创建实体的新实例Student
。它只是调用无参数构造函数。没有魔法涉及。城市字段使用值初始化。完成后,Morphia将获取从数据库返回的文档中的每个键,找到该映射字段并进行设置。在您的情况下,文档中没有城市键,因此Morphia永远不会设置该字段,并保留初始值。
通常,在像这样的实体上初始化字段是一种不好的做法。对于从数据库加载的每个实体,JVM必须将这些字段初始化为某个值,以便稍后覆盖它们。在您的某些情况下某些字段不会返回查询结果的情况下,在Morphia将新实例返回给您的应用程序后,这些值仍然存在。