Announcement Announcement Module
Collapse
No announcement yet.
Mongo : Losing type with generics in update, becomes LinkedHashMap instead Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mongo : Losing type with generics in update, becomes LinkedHashMap instead

    I have a simple case, on making a post, and then adding a comment, and then inserting them into my mongo collection :
    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);
    A little bit of MyPost's dead-simple code :
    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
    	....
    }
    And everything is still OK, and then i add a second comment, and issue a $push update :
    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
    		);
    After that, i fetch the document, and check the result, printing the first and second comments along with each's type :
    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());
    		}
    And it prints out :
    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
    Notice that the second comment has become a linkedHashMap object, which is the result of a $push update.
    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 :
    Code:
    	static class MyComments<T> {
    		List<T> comments = new ArrayList<>();
    		void add(T myBean) {
    			this.comments.add(myBean);
    		}
    	}
    into this :
    Code:
    	static class MyComments<T extends MyParentClass> {
    		List<T> comments = new ArrayList<>();
    		void add(T myBean) {
    			this.comments.add(myBean);
    		}
    	}
    and rerun the app again, the result would be :
    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
    The linkedHashMap has changed type into 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 ?
    Last edited by albert_kam; Mar 15th, 2012, 01:54 AM.

  • #2
    I think you stumbled over https://jira.springsource.org/browse/DATAMONGO-392.

    Comment


    • #3
      Hello again ..

      This was my original issue on https://jira.springsource.org/browse/DATAMONGO-407
      My bad on issueing this matter before posting it here.

      Will be very excited to see this feature getting supported ..

      Thank you !

      Comment

      Working...
      X