Skip to content

Commit

Permalink
Improve exception message when deriving collection name from type.
Browse files Browse the repository at this point in the history
We now provide a better worded exception message when trying to derive the collection name for a type that is not considered a user types (such as org.bson.Document).
Update the Javadoc to hint to the error.

Closes #4061
Original pull request: #4062.
  • Loading branch information
christophstrobl authored and mp911de committed Sep 16, 2022
1 parent 27e6b5a commit 018fe62
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
Expand Up @@ -138,7 +138,11 @@ public String determineCollectionName(@Nullable Class<?> entityClass) {
"No class parameter provided, entity collection can't be determined!");
}

return context.getRequiredPersistentEntity(entityClass).getCollection();
MongoPersistentEntity<?> persistentEntity = context.getPersistentEntity(entityClass);
if(persistentEntity == null) {
throw new MappingException(String.format("Collection name cannot be derived for type %s. Is it a store native type?", entityClass));
}
return persistentEntity.getCollection();
}

public Query getByIdInQuery(Collection<?> entities) {
Expand Down
Expand Up @@ -80,6 +80,7 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param entityClass must not be {@literal null}.
* @return never {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be derived from the type.
*/
String getCollectionName(Class<?> entityClass);

Expand Down Expand Up @@ -968,6 +969,8 @@ <T> T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions o
* fields specification. Must not be {@literal null}.
* @param replacement the replacement document. Must not be {@literal null}.
* @return the converted object that was updated or {@literal null}, if not found.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
Expand Down Expand Up @@ -1009,6 +1012,8 @@ default <T> T findAndReplace(Query query, T replacement, String collectionName)
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
Expand Down Expand Up @@ -1082,6 +1087,8 @@ default <T> T findAndReplace(Query query, T replacement, FindAndReplaceOptions o
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
Expand Down Expand Up @@ -1171,6 +1178,8 @@ <S, T> T findAndReplace(Query query, S replacement, FindAndReplaceOptions option
* {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the count of matching documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
long count(Query query, Class<?> entityClass);

Expand Down Expand Up @@ -1205,6 +1214,8 @@ <S, T> T findAndReplace(Query query, S replacement, FindAndReplaceOptions option
*
* @param entityClass must not be {@literal null}.
* @return the estimated number of documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.1
*/
default long estimatedCount(Class<?> entityClass) {
Expand Down Expand Up @@ -1265,6 +1276,8 @@ default long estimatedCount(Class<?> entityClass) {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the inserted object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> T insert(T objectToSave);

Expand All @@ -1291,6 +1304,8 @@ default long estimatedCount(Class<?> entityClass) {
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects that.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);

Expand All @@ -1309,6 +1324,8 @@ default long estimatedCount(Class<?> entityClass) {
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Collection<T> insertAll(Collection<? extends T> objectsToSave);

Expand All @@ -1330,6 +1347,8 @@ default long estimatedCount(Class<?> entityClass) {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> T save(T objectToSave);

Expand Down Expand Up @@ -1366,9 +1385,11 @@ default long estimatedCount(Class<?> entityClass) {
* the existing object. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @see Update
* @see AggregationUpdate
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
*/
UpdateResult upsert(Query query, UpdateDefinition update, Class<?> entityClass);

Expand Down Expand Up @@ -1420,9 +1441,11 @@ default long estimatedCount(Class<?> entityClass) {
* the existing. Must not be {@literal null}.
* @param entityClass class that determines the collection to use.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @see Update
* @see AggregationUpdate
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
*/
UpdateResult updateFirst(Query query, UpdateDefinition update, Class<?> entityClass);

Expand Down Expand Up @@ -1474,9 +1497,11 @@ default long estimatedCount(Class<?> entityClass) {
* the existing. Must not be {@literal null}.
* @param entityClass class of the pojo to be operated on. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @see Update
* @see AggregationUpdate
* @since 3.0
*/
UpdateResult updateMulti(Query query, UpdateDefinition update, Class<?> entityClass);

Expand Down Expand Up @@ -1524,6 +1549,8 @@ default long estimatedCount(Class<?> entityClass) {
*
* @param object must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
DeleteResult remove(Object object);

Expand All @@ -1547,6 +1574,8 @@ default long estimatedCount(Class<?> entityClass) {
* @param entityClass class that determines the collection to use.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws IllegalArgumentException when {@literal query} or {@literal entityClass} is {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
DeleteResult remove(Query query, Class<?> entityClass);

Expand Down Expand Up @@ -1594,6 +1623,8 @@ default long estimatedCount(Class<?> entityClass) {
* @param query the query document that specifies the criteria used to find and remove documents.
* @param entityClass class of the pojo to be operated on.
* @return the {@link List} converted objects deleted by this operation.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 1.5
*/
<T> List<T> findAllAndRemove(Query query, Class<T> entityClass);
Expand Down
Expand Up @@ -756,6 +756,8 @@ <T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOpt
* fields specification. Must not be {@literal null}.
* @param replacement the replacement document. Must not be {@literal null}.
* @return the converted object that was updated or {@link Mono#empty()}, if not found.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <T> Mono<T> findAndReplace(Query query, T replacement) {
Expand Down Expand Up @@ -795,6 +797,8 @@ default <T> Mono<T> findAndReplace(Query query, T replacement, String collection
* @return the converted object that was updated or {@link Mono#empty()}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <T> Mono<T> findAndReplace(Query query, T replacement, FindAndReplaceOptions options) {
Expand Down Expand Up @@ -865,6 +869,8 @@ default <T> Mono<T> findAndReplace(Query query, T replacement, FindAndReplaceOpt
* @return the converted object that was updated or {@link Mono#empty()}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType,
Expand Down Expand Up @@ -951,6 +957,8 @@ <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions
* {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the count of matching documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
Mono<Long> count(Query query, Class<?> entityClass);

Expand Down Expand Up @@ -1007,6 +1015,8 @@ <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions
*
* @param entityClass must not be {@literal null}.
* @return a {@link Mono} emitting the estimated number of documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.1
*/
default Mono<Long> estimatedCount(Class<?> entityClass) {
Expand Down Expand Up @@ -1045,6 +1055,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the inserted object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> insert(T objectToSave);

Expand All @@ -1070,7 +1082,9 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
*
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects .
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);

Expand All @@ -1089,6 +1103,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @return the saved objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Flux<T> insertAll(Collection<? extends T> objectsToSave);

Expand Down Expand Up @@ -1116,6 +1132,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param batchToSave the publisher which provides objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the type.
*/
<T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> batchToSave, Class<?> entityClass);

Expand Down Expand Up @@ -1155,6 +1173,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> save(T objectToSave);

Expand Down Expand Up @@ -1191,6 +1211,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> save(Mono<? extends T> objectToSave);

Expand Down Expand Up @@ -1224,6 +1246,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* the existing object. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
* @see Update
* @see AggregationUpdate
Expand Down Expand Up @@ -1278,6 +1302,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* the existing. Must not be {@literal null}.
* @param entityClass class that determines the collection to use.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
* @see Update
* @see AggregationUpdate
Expand Down Expand Up @@ -1333,6 +1359,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param entityClass class of the pojo to be operated on. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @see Update
* @see AggregationUpdate
*/
Expand Down Expand Up @@ -1379,6 +1407,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
*
* @param object must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
Mono<DeleteResult> remove(Object object);

Expand All @@ -1396,6 +1426,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
*
* @param objectToRemove must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
Mono<DeleteResult> remove(Mono<? extends Object> objectToRemove);

Expand All @@ -1415,6 +1447,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param query the query document that specifies the criteria used to remove a record.
* @param entityClass class that determines the collection to use.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
Mono<DeleteResult> remove(Query query, Class<?> entityClass);

Expand Down Expand Up @@ -1458,6 +1492,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* @param query the query document that specifies the criteria used to find and remove documents.
* @param entityClass class of the pojo to be operated on.
* @return the {@link Flux} converted objects deleted by this operation.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> findAllAndRemove(Query query, Class<T> entityClass);

Expand Down Expand Up @@ -1489,6 +1525,8 @@ default Mono<Long> estimatedCount(Class<?> entityClass) {
* specification.
* @param entityClass the parametrized type of the returned {@link Flux}.
* @return the {@link Flux} of converted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> tail(Query query, Class<T> entityClass);

Expand Down Expand Up @@ -1633,6 +1671,7 @@ <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, String inputCollec
*
* @param entityClass must not be {@literal null}.
* @return never {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be derived from the type.
* @since 2.1
*/
String getCollectionName(Class<?> entityClass);
Expand Down

0 comments on commit 018fe62

Please sign in to comment.