Announcement Announcement Module
Collapse
No announcement yet.
empty array being mapped to hashset instead of list Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • empty array being mapped to hashset instead of list

    Using spring mongo 1.1.0 release version, and mongo-java-driver 2.9.1 here.

    So, i have an arraylist that gets mapped to mongo without using any converters using the default mapper.

    If the list is not empty, i can read it back with the correct type, which is java.util.ArrayList

    But if if the list empty, when reading it back, it becomes a java.util.HashSet

    It doesnt seem to happen in my previous version of spring mongo 1.0.4.

  • #2
    What does your domain object look like?

    Comment


    • #3
      Dear Oliver,

      Here is a working single-java-file example that demonstrates the problem :

      Code:
      package kam.albert.lab.convert;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import org.bson.types.ObjectId;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.Scope;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      import org.springframework.data.mongodb.core.MongoOperations;
      import org.springframework.stereotype.Component;
      
      @Component
      @Scope(value="singleton")
      public class TestBug {
      
      	@Autowired private MongoOperations ops;
      
      	private static String collectionName = "test";
      
      	/**
      	 * @param args
      	 */
      	public static void main(String[] args) {
      		ApplicationContext ctx = new ClassPathXmlApplicationContext(
      			"test-context.xml"
      		);
      		TestBug bean = ctx.getBean(TestBug.class);
      		bean.test();
      	}
      
      	private void test() {
      		if (!this.ops.collectionExists(collectionName)) {
      			this.ops.createCollection(collectionName);
      		}
      
      		MyDomain domain = new MyDomain();
      
                      // COMMENT THIS LINE TO MAKE THE EXCEPTION SHOWS UP
      		domain.names.add("hello"); 
      
      		this.ops.insert(domain);
      
      		MyDomain dbDomain = this.ops.findById(domain.id, MyDomain.class);
      		List<String> values = dbDomain.names.getValues();
      		System.out.println("oink : " + values.getClass() + " : " + values);
      	}
      
      	private static class MyDomain {
      		private ObjectId id; // just for lookup later after insertion
      		private MyList<String> names;
      		MyDomain() {
      			this.id = new ObjectId();
      			this.names = new MyList<String>();
      		}
      	}
      
      	private static class MyList<T> extends MyPropertyBase<List<T>> {
      		MyList() {
      			this.value = new ArrayList<>();
      		}
      		void add(T elem) {
      			this.value.add(elem);
      		}
      		public List<T> getValues() {
      			return this.value;
      		}
      	}
      
      	private static class MyPropertyBase<T> {
      		T value;
      	}
      }
      The above is a working example with the output of :
      Code:
      oink : class java.util.ArrayList : [hello]
      One just need to comment the line :
      Code:
      domain.names.add("hello");
      to make the exception shows up :
      Code:
      Exception in thread "main" java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.List
      	at kam.albert.lab.convert.TestBug$MyList.getValues(TestBug.java:65)
      	at kam.albert.lab.convert.TestBug.test(TestBug.java:44)
      	at kam.albert.lab.convert.TestBug.main(TestBug.java:30)
      Please note that this doesnt happen in 1.0.4 version.

      Thank you !
      Last edited by albert_kam; Jan 8th, 2013, 06:39 AM.

      Comment


      • #4
        Hello, it's been quite a while. Is there any followups on this ?

        Comment


        • #5
          Any chance you can incorporate this into a tiny executable test case?

          Comment


          • #6
            Thanks for the reply.
            Any pointers how should i get started ?
            I am asking this because i am used to do simple tests with a running mongo instance, a custom spring xml file,
            tests like the example code above, where i consider it as runnable (a void main in there) and tiny (just 1 file).

            Comment


            • #7
              You don't even need a running Mongo instance. Write the test against MappingMongoConverter.read(DBObject, Class<?>)… set up a BasicDBObject with the data as it is returned from Mongo and hand in the type you want to unmarshal the data into…

              Comment


              • #8
                Hello again Oliver.
                Okay, i am trying to do this right now.
                Could you help me on how to construct a MappingMongoConverter instance ?
                I still have several conversion issues, if you guide me on how to do this, i will be more than happy to give you other tests.
                Thanks !

                Comment


                • #9
                  Well, have a look at the JavaDoc, have a look at the already existing unit tests [0].

                  [0] https://github.com/SpringSource/spri...UnitTests.java

                  Comment

                  Working...
                  X