Results 1 to 10 of 22

Thread: Property bug in Spring Data MongoDB Support 1.0.0.M1

Hybrid View

  1. #1
    Join Date
    Dec 2010
    Posts
    315

    Default Property bug in Spring Data MongoDB Support 1.0.0.M1

    I'm working on porting my tutorial
    Spring MVC 3: Using a Document-Oriented Database - MongoDB to use Spring Data Document - MongoDB Support 1.0.0.M1. However I think I've found a bug.

    The bug happens when your document (or your domain class) has an "id" property.

    Code:
    public class Person implements Serializable {
    
    	private String id;
    	private String firstName;
    	private String lastName;
    	private Double money;
    ...
    }
    Using plain MongoDB (no Spring Data support), to populate the Mongo with sample data, I call the init() method:

    Code:
    private void init() {
    		// Populate our MongoDB database
    
    		logger.debug("Init MongoDB users");
    		
    		// Drop existing collection
    		MongoDBFactory.getCollection("mydb","mycollection").drop();
    		// Retrieve collection. If not existing, create a new one
    		DBCollection coll = MongoDBFactory.getCollection("mydb","mycollection");
    		
    		// Create new object
    		BasicDBObject doc = new BasicDBObject();
    		// Generate random id using UUID type 4
    		// See http://en.wikipedia.org/wiki/Universally_unique_identifier
            doc.put("id", UUID.randomUUID().toString());
            doc.put("firstName", "John");
            doc.put("lastName", "Smith");
            doc.put("money", 1000);
            coll.insert(doc);
    		
            // Create new object
            doc = new BasicDBObject();
    		// Generate random id using UUID type 4
            doc.put("id", UUID.randomUUID().toString());
            doc.put("firstName", "Jane");
            doc.put("lastName", "Adams");
            doc.put("money", 2000);
            coll.insert(doc);
            
            // Create new object
            doc = new BasicDBObject();
    		// Generate random id using UUID type 4
            doc.put("id", UUID.randomUUID().toString());
            doc.put("firstName", "Jeff");
            doc.put("lastName", "Mayer");
            doc.put("money", 3000);
            coll.insert(doc);
    		
    	}
    Calling db.mycollection.find() on the Mongo console:
    Code:
    { "_id" : ObjectId("4d5e7b3bfdece02281f253a4"), "id" : "f1e6b8b2-9d68-495c-9d6e-b81cc35cf9bc", "firstName" : "John", "lastName" : "Smith", "money" : 1000 }
    { "_id" : ObjectId("4d5e7b3bfdece02282f253a4"), "id" : "39f6ebfb-10cf-4702-a5b8-8bc2489cebcc", "firstName" : "Jane", "lastName" : "Adams", "money" : 2000 }
    { "_id" : ObjectId("4d5e7b3bfdece02283f253a4"), "id" : "f4932004-c320-47e4-b4b3-7d07f3aaabb9", "firstName" : "Jeff", "lastName" : "Mayer", "money" : 3000 }
    Notice that all properties, id, firstName, lastName, and money are present. We also have another property "_id". This works fine.

    Now, I ported the code to use Spring Data MongoDb. To populate Mongo with data, I call the following init() method:
    Code:
    private void init() {
    		// Populate our MongoDB database
    
    		logger.debug("Init MongoDB users");
    		
    		// Drop existing collection
    		mongoTemplate.dropCollection("mycollection");
    		
    		// Create new object
    		Person p = new Person ();
    		p.setId(UUID.randomUUID().toString());
    		p.setFirstName("John");
    		p.setLastName("Smith");
    		p.setMoney(1000.0);
    		
    		// Insert to db
    	    mongoTemplate.insert("mycollection", p);
    
    	    // Create new object
    		p = new Person ();
    		p.setId(UUID.randomUUID().toString());
    		p.setFirstName("Jane");
    		p.setLastName("Adams");
    		p.setMoney(2000.0);
    		
    		// Insert to db
    	    mongoTemplate.insert("mycollection", p);
            
    	    // Create new object
    		p = new Person ();
    		p.setId(UUID.randomUUID().toString());
    		p.setFirstName("Jeff");
    		p.setLastName("Mayer");
    		p.setMoney(3000.0);
    		
    		// Insert to db
    	    mongoTemplate.insert("mycollection", p);
    	}
    Notice I used the template:
    Code:
    mongoTemplate.insert("mycollection", p);
    Calling db.mycollection.find() on the Mongo console:
    Code:
    { "_id" : "69133244-fcc0-42b2-aa59-308f00c75860", "firstName" : "John", "money" : 1000, "lastName" : "Smith" }
    { "_id" : "45d236ff-6a38-4767-a973-6f3d70ff2448", "firstName" : "Jane", "money" : 2000, "lastName" : "Adams" }
    { "_id" : "9dcba269-9ed5-45c6-887e-a2de8fec334d", "firstName" : "Jeff", "money" : 3000, "lastName" : "Mayer" }
    Notice the "id" property is gone. Actually it has been merged with the property "_id". In the original implementation, these are two separate properties.

    The real problem starts when you try to update and remove the item by "id". But the fundamental question is why the discrepancy between the two implementations?

    As a workaround, I had to name the property id to something different like "pid" and everything works as expected with Spring Data MongoDb.
    Last edited by skram; Feb 18th, 2011 at 08:25 AM.

  2. #2
    Join Date
    Dec 2010
    Posts
    315

    Default

    By the way here's the new tutorial that uses the Spring Data MongoDB 1.0.0.M1

    Spring Data - MongoDB Tutorial at http://krams915.blogspot.com/2011/02...-tutorial.html

  3. #3

    Default

    Thank you, skram. Regarding the id property, as far as I understand it, spring-data-document implementation hardcodes the "id" field to be the database id (_id in json). This is not good, we should add an annotation to specify which field is the database id field(e.g., @Id), so this problem will not appear. I think this would be covered in the JIRA ticket I filed: DATADOC-40 Add support for specifying attributes to entitties, e.g., collection name, field names, etc..
    Oruganti Shanker

  4. #4
    Join Date
    Dec 2010
    Posts
    315

    Default

    @oshankerShutter, thanks for verifying this problem. I thought I'm just having hallucinations I've checked the Spring Data for MongoDB source and you're right. Somehow the id is hard coded. I wouldn't call it bug or wrong behavior if the native MongoDB behaves exactly the same, but it behaves differently.

  5. #5
    Join Date
    Aug 2004
    Posts
    1,104

    Default

    You are right that the current bean property based SimpleMongoConverter maps any property named 'id' or '_id' to the Mongo _id field. We are considering other solutions for mapping and we could also add configuration for the SimpleMongoConverter to change the _id mapping behavior. I'll take a look at adding the latter for our M2 release.

    -Thomas
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  6. #6
    Join Date
    Dec 2010
    Posts
    315

    Default

    @trisberg, thanks for the confirmation. I can't wait for the M2 release. I'm sure it's gonna be a great release as well

  7. #7
    Join Date
    Jul 2011
    Posts
    6

    Default

    > The real problem starts when you try to update and remove the item by "id". But the fundamental question is why the discrepancy between the two implementations?
    When you try to update a record in an entity with a field of name 'id' in release 1.1.4 you get an internal error which tells you nothing about this cause (see attached screen). At least the error handling should therefore have been improved in this JIRA:
    https://jira.springsource.org/browse/DATADOC-44
    Attached Images Attached Images

  8. #8

    Default

    what does this have to with spring roo? You are not using mongodb on top of it

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •