I have a simple case, on making a post, and then adding a comment, and then inserting them into my mongo collection :
A little bit of MyPost's dead-simple code :Code:// create a post and add a comment String postId = "post1"; MyPost myPost = new MyPost(postId); myPost.addComment("1", "my first comment"); // store it this.ops.insert(myPost, COLLECTION_NAME);
And everything is still OK, and then i add a second comment, and issue a $push update :Code:public class MyPost { MyComments<MyComment> myComments = new MyComments<>(); ... public MyComment addComment(String id, String comment) { MyComment myComment = new MyComment(id, comment); this.myComments.add(myComment); return myComment; } static class MyComments<T> { List<T> comments = new ArrayList<>(); void add(T myBean) { this.comments.add(myBean); } } // MyComment class is just a normal bean .... }
After that, i fetch the document, and check the result, printing the first and second comments along with each's type :Code:// create a second comment MyComment comment2 = myPost.addComment("2", "my second comment"); // update the comments, push the second comment this.ops.updateFirst( Query.query(Criteria.where("_id").is(postId)), new Update().push("myComments.comments", comment2), COLLECTION_NAME );
And it prints out :Code:// retrieve the newly updated bean2 // (strangely, fetching the old bean1 will work just fine. just change the is("bean2") into is("bean1")) MyPost domain = this.ops.findOne( Query.query(Criteria.where("_id").is(postId)), MyPost.class, COLLECTION_NAME ); System.out.println("\nprinting comment types :"); for (Object comment : domain.myComments.comments) { System.out.println("\t" + comment + " --> " + comment.getClass()); }
Notice that the second comment has become a linkedHashMap object, which is the result of a $push update.Code:printing comment types : kam.albert.domain.test.case1.MyPost$MyComment@1095a1 --> class kam.albert.domain.test.case1.MyPost$MyComment {commentId=2, comment=my second comment} --> class java.util.LinkedHashMap
The first comment is fine though, which is the result of first insertion.
My expectation is that the second comment's type is the same as the first comment, which is MyComment.class
If i modify MyPost.java, from this :
into this :Code:static class MyComments<T> { List<T> comments = new ArrayList<>(); void add(T myBean) { this.comments.add(myBean); } }
and rerun the app again, the result would be :Code:static class MyComments<T extends MyParentClass> { List<T> comments = new ArrayList<>(); void add(T myBean) { this.comments.add(myBean); } }
The linkedHashMap has changed type into MyParentClass.Code:printing comment types : kam.albert.domain.test.case1.MyPost$MyComment@27b534 --> class kam.albert.domain.test.case1.MyPost$MyComment kam.albert.domain.test.case1.MyParentClass@e99a3d --> class kam.albert.domain.test.case1.MyParentClass
To make this work as expected, i have to modify it into this, but this means i will not be able to make use of the generics :
Code:static class MyComments { List<MyComment> comments = new ArrayList<>(); void add(MyComment myBean) { this.comments.add(myBean); } }
TestThatFails.java is here :
http://pastebin.com/8Qf8Lapn
MyPost.java is in here :
http://pastebin.com/kR24hwMR
test-context.xml is here :
http://pastebin.com/hcvWwY8H
Any ideas what can be done ?


Reply With Quote
