Browse Source

DATADOC-188 - Allow controlling repository index creation.

Disabled index creation for repository query methods by default. Added property on MongoRepositoryFactoryBean to enable index creation and expose that via 'create-query-indexes' attribute on the namespace.
pull/1/head
Oliver Gierke 15 years ago
parent
commit
a2687b6688
  1. 1
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java
  2. 30
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/SimpleMongoRepositoryConfiguration.java
  3. 18
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/repository/MongoRepositoryFactoryBean.java
  4. 8
      spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd
  5. 86
      spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/repository/MongoRepositoryFactoryBeanUnitTests.java
  6. 78
      spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/repository/RepositoryIndexCreationIntegrationTests.java
  7. 21
      spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/RepositoryIndexCreationIntegrationTests-context.xml

1
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java

@ -49,5 +49,6 @@ public class MongoRepositoryConfigParser extends @@ -49,5 +49,6 @@ public class MongoRepositoryConfigParser extends
BeanDefinitionRegistry registry, Object beanSource) {
builder.addPropertyReference("template", context.getMongoTemplateRef());
builder.addPropertyValue("createIndexesForQueryMethods", context.getCreateQueryIndexes());
}
}

30
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/SimpleMongoRepositoryConfiguration.java

@ -34,6 +34,7 @@ public class SimpleMongoRepositoryConfiguration @@ -34,6 +34,7 @@ public class SimpleMongoRepositoryConfiguration
RepositoryConfig<SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration, SimpleMongoRepositoryConfiguration> {
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate";
/**
@ -57,6 +58,17 @@ public class SimpleMongoRepositoryConfiguration @@ -57,6 +58,17 @@ public class SimpleMongoRepositoryConfiguration
return StringUtils.hasText(templateRef) ? templateRef : DEFAULT_MONGO_TEMPLATE_REF;
}
/**
* Returns whether to create indexes for query methods.
*
* @return
*/
public boolean getCreateQueryIndexes() {
String createQueryIndexes = getSource().getAttribute(CREATE_QUERY_INDEXES);
return StringUtils.hasText(createQueryIndexes) ? Boolean.parseBoolean(createQueryIndexes) : false;
}
/*
* (non-Javadoc)
*
@ -98,6 +110,8 @@ public class SimpleMongoRepositoryConfiguration @@ -98,6 +110,8 @@ public class SimpleMongoRepositoryConfiguration
SingleRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> {
String getMongoTemplateRef();
boolean getCreateQueryIndexes();
}
/**
@ -130,6 +144,15 @@ public class SimpleMongoRepositoryConfiguration @@ -130,6 +144,15 @@ public class SimpleMongoRepositoryConfiguration
return getAttribute(MONGO_TEMPLATE_REF);
}
/* (non-Javadoc)
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getCreateQueryIndexes()
*/
public boolean getCreateQueryIndexes() {
String attribute = getAttribute(CREATE_QUERY_INDEXES);
return attribute == null ? false : Boolean.parseBoolean(attribute);
}
}
/**
@ -162,5 +185,12 @@ public class SimpleMongoRepositoryConfiguration @@ -162,5 +185,12 @@ public class SimpleMongoRepositoryConfiguration
return getParent().getMongoTemplateRef();
}
/* (non-Javadoc)
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getCreateQueryIndexes()
*/
public boolean getCreateQueryIndexes() {
return getParent().getCreateQueryIndexes();
}
}
}

18
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/repository/MongoRepositoryFactoryBean.java

@ -59,6 +59,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten @@ -59,6 +59,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
RepositoryFactoryBeanSupport<T, S, ID> {
private MongoTemplate template;
private boolean createIndexesForQueryMethods = false;
/**
* Configures the {@link MongoTemplate} to be used.
@ -71,6 +72,15 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten @@ -71,6 +72,15 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
this.template = template;
}
/**
* Configures whether to automatically create indexes for the properties referenced in a query method.
*
* @param createIndexesForQueryMethods the createIndexesForQueryMethods to set
*/
public void setCreateIndexesForQueryMethods(boolean createIndexesForQueryMethods) {
this.createIndexesForQueryMethods = createIndexesForQueryMethods;
}
/*
* (non-Javadoc)
*
@ -82,7 +92,11 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten @@ -82,7 +92,11 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
protected final RepositoryFactorySupport createRepositoryFactory() {
RepositoryFactorySupport factory = getFactoryInstance(template);
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
if (createIndexesForQueryMethods) {
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(template));
}
return factory;
}
@ -276,7 +290,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten @@ -276,7 +290,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
*
* @author Oliver Gierke
*/
private static class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTreeMongoQuery> {
static class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTreeMongoQuery> {
private static final Set<Type> GEOSPATIAL_TYPES = new HashSet<Part.Type>(Arrays.asList(Type.NEAR, Type.WITHIN));
private static final Log LOG = LogFactory.getLog(IndexEnsuringQueryCreationListener.class);

8
spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd

@ -118,6 +118,14 @@ The password to use when connecting to a MongoDB server. @@ -118,6 +118,14 @@ The password to use when connecting to a MongoDB server.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="create-query-indexes" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation>
Enables creation of indexes for queries that get derived from the method name
and thus reference domain class properties. Defaults to false.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:attributeGroup>
<xsd:element name="repositories">

86
spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/repository/MongoRepositoryFactoryBeanUnitTests.java

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
/*
* Copyright 2011 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.document.mongodb.repository;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.document.mongodb.MongoTemplate;
import org.springframework.data.document.mongodb.convert.MongoConverter;
import org.springframework.data.document.mongodb.repository.MongoRepositoryFactoryBean.IndexEnsuringQueryCreationListener;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.core.support.QueryCreationListener;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.test.util.ReflectionTestUtils;
/**
* Unit tests for {@link MongoRepositoryFactoryBean}.
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class MongoRepositoryFactoryBeanUnitTests {
@Mock
MongoTemplate template;
@Mock
MongoConverter converter;
@Mock
@SuppressWarnings("rawtypes")
MappingContext context;
@Test
@SuppressWarnings("rawtypes")
public void addsIndexEnsuringQueryCreationListenerIfConfigured() {
MongoRepositoryFactoryBean factory = new MongoRepositoryFactoryBean();
factory.setCreateIndexesForQueryMethods(true);
List<QueryCreationListener<?>> listeners = getListenersFromFactory(factory);
assertThat(listeners.size(), is(1));
assertThat(listeners.get(0), is(instanceOf(IndexEnsuringQueryCreationListener.class)));
}
@Test
@SuppressWarnings("rawtypes")
public void doesNotAddIndexEnsuringQueryCreationListenerByDefault() {
List<QueryCreationListener<?>> listeners = getListenersFromFactory(new MongoRepositoryFactoryBean());
assertThat(listeners.isEmpty(), is(true));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private List<QueryCreationListener<?>> getListenersFromFactory(MongoRepositoryFactoryBean factoryBean) {
when(template.getConverter()).thenReturn(converter);
when(converter.getMappingContext()).thenReturn(context);
factoryBean.setTemplate(template);
factoryBean.afterPropertiesSet();
RepositoryFactorySupport factory = factoryBean.createRepositoryFactory();
return (List<QueryCreationListener<?>>) ReflectionTestUtils.getField(factory, "queryPostProcessors");
}
}

78
spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/repository/RepositoryIndexCreationIntegrationTests.java

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
/*
* Copyright 2011 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.document.mongodb.repository;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.document.mongodb.CollectionCallback;
import org.springframework.data.document.mongodb.MongoOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
/**
* Integration test for index creation for query methods.
*
* @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class RepositoryIndexCreationIntegrationTests {
@Autowired
MongoOperations operations;
@After
public void tearDown() {
operations.dropCollection(Person.class);
}
@Test
public void testname() {
operations.execute(Person.class, new CollectionCallback<Void>() {
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> indexInfo = collection.getIndexInfo();
assertThat(indexInfo.isEmpty(), is(false));
assertThat(indexInfo.size(), is(greaterThan(2)));
assertThat(getIndexNamesFrom(indexInfo), hasItems("findByLastname", "findByFirstnameNotIn"));
return null;
}
});
}
private static List<String> getIndexNamesFrom(List<DBObject> indexes) {
List<String> result = new ArrayList<String>();
for (DBObject dbObject : indexes) {
result.add(dbObject.get("name").toString());
}
return result;
}
}

21
spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/RepositoryIndexCreationIntegrationTests-context.xml

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<mongo:db-factory dbname="repositories"/>
<mongo:mapping-converter base-package="org.springframework.data.document.mongodb.repository"/>
<bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
<constructor-arg ref="mappingConverter"/>
</bean>
<mongo:repositories base-package="org.springframework.data.document.mongodb.repository"
create-query-indexes="true" />
</beans>
Loading…
Cancel
Save