Results 1 to 6 of 6

Thread: Generating Unique Exception

  1. #1

    Default Generating Unique Exception

    I have set up a simple Document called User:
    public class User
    {
    @Id
    private String username;
    }

    I have set up my UserRepository
    public interface UserRepository extends MongoRepository<User, String>
    {
    User findByUsername(String username);
    }

    I have set up in my applicationContext to generate exceptions
    <mongo:mongo host="localhost" port="27017" id="mongo"/>
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.Mongo Template">
    <constructor-arg ref="mongo" />
    <constructor-arg value="testdb" />
    <property name="writeResultChecking" value="EXCEPTION"/>
    <property name="writeConcern" value="SAFE"/>
    </bean>

    Yet, when i insert a second user with same username, while the insert fails, i am not getting an exception. This is using the snapshot build: 1.1.0.BUILD-SNAPSHOT.
    Is this a bug, or am i still missing some configuration?

  2. #2

    Default

    I see in debugger that the code goes to update when id is already in there. Perhaps the issue is that if you set the id, the Spring layer interprets it as an update. So, when using username as the id we have no choice but to to do a manual check if user exists before the persist is done.
    A good option would be to set this to be insertNew. Alternatively, i can set the username as unique index and not as id.

  3. #3
    Join Date
    Oct 2005
    Location
    Cambridge, UK
    Posts
    31

    Default

    Hi,

    I just spotted this and am working in this area, so I thought I'd contribute.

    As far as I understand the @Id annotation (or a field called 'id' if no annotations is present), maps to the _id attribute in the mongo document.

    Therefore, if you provide a value, this will be used.

    For example, in using MongoDB for storing my Spring Security user credentials, I have the following:
    Code:
    	@Indexed(unique=true)
    	private final String email;
    	
    	@Id
    	private final UUID publicUuid;
    In this case, a different publicUuid will be a different document.

    Where I'm stuck though is that I have a test as follows that fails, and I think should pass (i.e. throw the exception):
    Code:
    	@Test(expected=DuplicateKeyException.class)
    	public void duplicateEmailShouldThrowException() {
    		
    		SimpleUserDetails user1 = new SimpleUserDetails("unique@emailxyz.info", "password", "Me", "Ape");
    		user1 = repo.save(user1);
    		assertNotNull(user1);
    		
    		SimpleUserDetails user2 = new SimpleUserDetails("unique@emailxyz.info", "diffpassword", "NotMe", "NotApe");
    		user2 = repo.save(user2);
    		assertNotNull(user2); // should never get here
    	}
    I think this is a bug/pending feature...
    Last edited by nealeu; Jun 21st, 2012 at 02:22 PM. Reason: formatting
    Lead committer on fuzzydb - the database for when yes/no is just plain annoying!
    @nealeu & @fuzzydb

  4. #4
    Join Date
    Oct 2005
    Location
    Cambridge, UK
    Posts
    31

    Default

    I've looked into this, and it looks like the WriteResult returned from collection.save(dbDoc) in org.springframework.data.mongodb.core.MongoTemplat e.saveDBObject(String, DBObject, Class<?>) is ignored.
    Lead committer on fuzzydb - the database for when yes/no is just plain annoying!
    @nealeu & @fuzzydb

  5. #5
    Join Date
    Oct 2005
    Location
    Cambridge, UK
    Posts
    31

    Default

    I'm looking further at this and drilling deeper, the ignored result should not be important as we should get a MongoException...
    Lead committer on fuzzydb - the database for when yes/no is just plain annoying!
    @nealeu & @fuzzydb

  6. #6
    Join Date
    Oct 2005
    Location
    Cambridge, UK
    Posts
    31

    Smile Sorted..

    The reason the exception is not getting thrown is that the default WriteConcern on MongoTemplate is NONE.

    The following gets me around the problem:

    Code:
    @Configuration
    @Profile("default") 
    public class DefaultMongoConfig extends AbstractMongoConfiguration {
    
    	@Override
    	protected String getDatabaseName() {
    		return "dev-mongodb";
    	}
    
    	@Override
    	public Mongo mongo() throws Exception {
    		return new Mongo("127.0.0.1");
    	}
    	
    	@Override
    	public MongoTemplate mongoTemplate() throws Exception {
    		MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
    		mongoTemplate.setWriteConcern(WriteConcern.SAFE);
    		return mongoTemplate;
    	}
    }
    Lead committer on fuzzydb - the database for when yes/no is just plain annoying!
    @nealeu & @fuzzydb

Posting Permissions

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