Skip to content

Commit

Permalink
DATAMONGO-348 - Polishing of lazy loading implementation.
Browse files Browse the repository at this point in the history
Extracted DelegatingDbRefResolver and associates from MappingMongoConverter. Let MongoDbFactory expose PersistenceExceptionTranslator only to prevent invalid dependency to core package. Renamed DbRefResolveCallback to ResolverCallback. Removed AbstractDbRefResolver and moved the functionality implemented there (triggering of exception translation) into the DbRefResolver.

MappingMongoConverter now uses a slightly extended version of DbRefResolver so that we can essentially replace the MongoDbFactory dependency with the DbRefResolver one.

Added support for Objenesis based lazy-loading proxies to support domain classes without a default constructor. Explicitly check for Spring 4 being present as with it the default ProxyFactory already supports that out of the box.

Added missing JavaDoc and assertions. A lot of cleanups and removal of deprecation warnings in test cases.
  • Loading branch information
odrotbohm committed Nov 4, 2013
1 parent b808fd3 commit c3f8f1e
Show file tree
Hide file tree
Showing 54 changed files with 1,127 additions and 875 deletions.
8 changes: 8 additions & 0 deletions spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<properties>
<validation>1.0.0.GA</validation>
<objenesis>1.3</objenesis>
</properties>

<dependencies>
Expand Down Expand Up @@ -119,6 +120,13 @@
<version>${validation}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.UncategorizedDataAccessException;

/**
* @author Oliver Gierke
*/
public class LazyLoadingException extends UncategorizedDataAccessException {

private static final long serialVersionUID = -7089224903873220037L;

/**
* @param msg
* @param cause
*/
public LazyLoadingException(String msg, Throwable cause) {
super(msg, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.springframework.data.mongodb;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator;

import com.mongodb.DB;
Expand Down Expand Up @@ -48,7 +49,7 @@ public interface MongoDbFactory {
/**
* Exposes a shared {@link MongoExceptionTranslator}.
*
* @return
* @return will never be {@literal null}.
*/
MongoExceptionTranslator getExceptionTranslator();
PersistenceExceptionTranslator getExceptionTranslator();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy;
import org.springframework.data.mongodb.core.mapping.Document;
Expand Down Expand Up @@ -178,8 +180,11 @@ public CustomConversions customConversions() {
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), mongoMappingContext());

DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
converter.setCustomConversions(customConversions());

return converter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.convert.EntityReader;
import org.springframework.data.mapping.PersistentEntity;
Expand All @@ -59,6 +60,8 @@
import org.springframework.data.mongodb.core.aggregation.Fields;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoWriter;
Expand Down Expand Up @@ -145,6 +148,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
private final MongoConverter mongoConverter;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
private final MongoDbFactory mongoDbFactory;
private final PersistenceExceptionTranslator exceptionTranslator;
private final QueryMapper queryMapper;
private final UpdateMapper updateMapper;

Expand Down Expand Up @@ -198,6 +202,7 @@ public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverte
Assert.notNull(mongoDbFactory);

this.mongoDbFactory = mongoDbFactory;
this.exceptionTranslator = mongoDbFactory.getExceptionTranslator();
this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter;
this.queryMapper = new QueryMapper(this.mongoConverter);
this.updateMapper = new UpdateMapper(this.mongoConverter);
Expand Down Expand Up @@ -1796,7 +1801,7 @@ protected void handleAnyWriteResultErrors(WriteResult writeResult, DBObject quer
* @return
*/
private RuntimeException potentiallyConvertRuntimeException(RuntimeException ex) {
RuntimeException resolved = this.mongoDbFactory.getExceptionTranslator().translateExceptionIfPossible(ex);
RuntimeException resolved = this.exceptionTranslator.translateExceptionIfPossible(ex);
return resolved == null ? ex : resolved;
}

Expand All @@ -1822,7 +1827,9 @@ private void handleCommandError(CommandResult result, DBObject source) {
}

private static final MongoConverter getDefaultMongoConverter(MongoDbFactory factory) {
MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext());

DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
converter.afterPropertiesSet();
return converter;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-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.
Expand All @@ -19,6 +19,7 @@

import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.util.Assert;
Expand All @@ -34,16 +35,16 @@
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Thomas Darimont
* @author Thomas Darimont
*/
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {

private final Mongo mongo;
private final String databaseName;
private final boolean mongoInstanceCreated;
private final UserCredentials credentials;
private final PersistenceExceptionTranslator exceptionTranslator;
private WriteConcern writeConcern;
private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();

/**
* Create an instance of {@link SimpleMongoDbFactory} given the {@link Mongo} instance and database name.
Expand Down Expand Up @@ -74,6 +75,7 @@ public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials cr
* @throws UnknownHostException
* @see MongoURI
*/
@SuppressWarnings("deprecation")
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())), true);
}
Expand All @@ -90,6 +92,7 @@ private SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials c
this.databaseName = databaseName;
this.mongoInstanceCreated = mongoInstanceCreated;
this.credentials = credentials == null ? UserCredentials.NO_CREDENTIALS : credentials;
this.exceptionTranslator = new MongoExceptionTranslator();
}

/**
Expand Down Expand Up @@ -140,12 +143,13 @@ public void destroy() throws Exception {
private static String parseChars(char[] chars) {
return chars == null ? null : String.valueOf(chars);
}

/* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getExceptionTranslator()
*/
@Override
public MongoExceptionTranslator getExceptionTranslator() {
return this.exceptionTranslator;
}

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getExceptionTranslator()
*/
@Override
public PersistenceExceptionTranslator getExceptionTranslator() {
return this.exceptionTranslator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,34 @@
*/
package org.springframework.data.mongodb.core.convert;

import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;

import com.mongodb.DBRef;

/**
* Used to resolve associations annotated with {@link org.springframework.data.mongodb.core.mapping.DBRef}.
*
* @author Thomas Darimont
*/
interface DbRefResolver {
public interface DbRefResolver {

/**
* @param property will never be {@literal null}.
* @param callback will never be {@literal null}.
* @return
*/
Object resolveDbRef(MongoPersistentProperty property, DbRefResolverCallback callback);

/**
* @param property
* @param callback
* Creates a {@link DBRef} instance for the given {@link org.springframework.data.mongodb.core.mapping.DBRef}
* annotation, {@link MongoPersistentEntity} and id.
*
* @param annotation will never be {@literal null}.
* @param entity will never be {@literal null}.
* @param id will never be {@literal null}.
* @return
*/
Object resolve(MongoPersistentProperty property, DbRefResolveCallback callback);
DBRef createDbRef(org.springframework.data.mongodb.core.mapping.DBRef annotation, MongoPersistentEntity<?> entity,
Object id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
* Callback interface to be used in conjunction with {@link DbRefResolver}.
*
* @author Thomas Darimont
* @author Oliver Gierke
*/
interface DbRefResolveCallback {
public interface DbRefResolverCallback {

/**
* @param property
* Resolve the final object for the given {@link MongoPersistentProperty}.
*
* @param property will never be {@literal null}.
* @return
*/
Object resolve(MongoPersistentProperty property);
Expand Down
Loading

0 comments on commit c3f8f1e

Please sign in to comment.