Morphia projection behavior for instance variable with default value

こ雲淡風輕ζ 提交于 2019-12-24 00:07:16

问题


I'm not sure if its the way Morphia is designed but here it goes...

Student.class (methods omitted)

@Entity(value = "students", noClassnameStored = true)
public class Student
{
    @Id
    private String id = new ObjectId().toString();
    private String name;
    private String city = "London"; // Default Value
}

NOTE: That I have assigned a DEFAULT value to Instance variable city. Now the code...

    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);

And, now the output...

----- 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'}

Now, 4 questions about the Morphia behaviour...

Q1. For Mr. Bond, I did not change the city and excluded city from the projected list, yet the default value of the city is printed as London. Should'nt this be null?

Q2. For Mr. Bourne, I did change the city to New York but still during the projection, it picked up the default value and showed London. Should'nt this be null as well?

I havent yet seen the Projection.class from Morphia (intend to do so tonight) but it seems that for exclusions, Morphia seems to pick up the default value and does not over-ride with null. Now this becomes a hindrance since I do not have any way to provide default value to my Instance Variables without exposing them to client's...

Q3. Is this Morphia or a MongoD Java Driver behavior/issue?

And the final question...

Q4. Any known workaround for this?

I have googled around but did not come around any solution or explanation so far...

Thanks in advance...

SG


回答1:


When Morphia is reading your documents from the query results, the first thing it does is create a new instance of your entity, Student. It just invokes the no argument constructor. There's no magic involved. The city field is initialized with a value. Once that's done, Morphia will take each key in the document returned from the database, find that mapped field, and set it. In your case, there is not city key in the document and so that field is never set by Morphia leaving the initialized value in place.

In general, initializing fields on entities like this is a bad practice. For every entity loaded from the database, the JVM has to initialize those fields to some value only to overwrite them later. In cases such as yours where certain fields don't come back in a query result, those values remain after Morphia returns the new instances back to your application.



来源:https://stackoverflow.com/questions/37170629/morphia-projection-behavior-for-instance-variable-with-default-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!