Browse Source

DATAMONGO-651 - MongoTemplate now throws Mongo-specific exception with WriteResult.

If the WriteResultChecking is set to EXCEPTION on a MongoTemplate, we now throw a Mongo-specific exception that captures both the WriteResult and MongoActionOperation for further evaluation.
pull/33/head
Oliver Gierke 13 years ago
parent
commit
0cdec56a27
  1. 72
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDataIntegrityViolationException.java
  2. 4
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  3. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

72
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDataIntegrityViolationException.java

@ -0,0 +1,72 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.mongodb.core.MongoActionOperation;
import org.springframework.util.Assert;
import com.mongodb.WriteResult;
/**
* Mongo-specific {@link DataIntegrityViolationException}.
*
* @author Oliver Gierke
*/
public class MongoDataIntegrityViolationException extends DataIntegrityViolationException {
private static final long serialVersionUID = -186980521176764046L;
private final WriteResult writeResult;
private final MongoActionOperation actionOperation;
/**
* Creates a new {@link MongoDataIntegrityViolationException} using the given message and {@link WriteResult}.
*
* @param message the exception message
* @param writeResult the {@link WriteResult} that causes the exception, must not be {@literal null}.
* @param actionOperation the {@link MongoActionOperation} that caused the exception, must not be {@literal null}.
*/
public MongoDataIntegrityViolationException(String message, WriteResult writeResult,
MongoActionOperation actionOperation) {
super(message);
Assert.notNull(writeResult, "WriteResult must not be null!");
Assert.notNull(actionOperation, "MongoActionOperation must not be null!");
this.writeResult = writeResult;
this.actionOperation = actionOperation;
}
/**
* Returns the {@link WriteResult} that caused the exception.
*
* @return the writeResult
*/
public WriteResult getWriteResult() {
return writeResult;
}
/**
* Returns the {@link MongoActionOperation} in which the current exception occured.
*
* @return the actionOperation
*/
public MongoActionOperation getActionOperation() {
return actionOperation;
}
}

4
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -44,7 +44,6 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.authentication.UserCredentials; import org.springframework.data.authentication.UserCredentials;
@ -53,6 +52,7 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.MongoDataIntegrityViolationException;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.MongoConverter;
@ -1647,7 +1647,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
} }
if (writeResultChecking == WriteResultChecking.EXCEPTION) { if (writeResultChecking == WriteResultChecking.EXCEPTION) {
throw new DataIntegrityViolationException(message); throw new MongoDataIntegrityViolationException(message, writeResult, operation);
} else { } else {
LOGGER.error(message); LOGGER.error(message);
return; return;

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*; import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Update.*; import static org.springframework.data.mongodb.core.query.Update.*;
@ -30,6 +31,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import org.hamcrest.CoreMatchers;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -50,6 +52,7 @@ import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.annotation.Version; import org.springframework.data.annotation.Version;
import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.MongoDataIntegrityViolationException;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
@ -275,7 +278,8 @@ public class MongoTemplateTests {
} catch (DataIntegrityViolationException e) { } catch (DataIntegrityViolationException e) {
assertThat( assertThat(
e.getMessage(), e.getMessage(),
startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId")); CoreMatchers
.startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId"));
} }
} }
@ -1570,6 +1574,29 @@ public class MongoTemplateTests {
assertThat(person.getFirstName(), is(nullValue())); assertThat(person.getFirstName(), is(nullValue()));
} }
/**
* @see DATAMONGO-651
*/
@Test
public void throwsMongoSpecificExceptionForDataIntegrityViolations() {
WriteResult result = mock(WriteResult.class);
when(result.getError()).thenReturn("ERROR");
MongoActionOperation operation = MongoActionOperation.INSERT;
MongoTemplate mongoTemplate = new MongoTemplate(factory);
mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);
try {
mongoTemplate.handleAnyWriteResultErrors(result, null, operation);
fail("Expected MonogoDataIntegrityViolationException!");
} catch (MongoDataIntegrityViolationException o_O) {
assertThat(o_O.getActionOperation(), is(operation));
assertThat(o_O.getWriteResult(), is(result));
}
}
static class MyId { static class MyId {
String first; String first;

Loading…
Cancel
Save