2012-09-05 39 views
11

Tengo una colección llamada Products en mi base de datos MongoDB, que está representada por la interfaz IProductPrice en mi código Java. La siguiente declaración de repositorio hace que Fecha de primavera mire a la colección db.collection: Intelliprice.iProductPrice.Cómo configurar el nombre de la colección MongoDb para una clase en Spring Data

Quiero que lo configure para buscar en db.collection: Intelliprice.Products utilizando una configuración externa en lugar de poner una anotación @Collection(..) en IProductPrice. es posible? ¿Cómo puedo hacer esto?

public interface ProductsRepository extends 
    MongoRepository<IProductPrice, String> { 
} 

Respuesta

10

La única forma en que actualmente se puede lograr esto es mediante la anotación de su clase de dominio con @Document utilizando la propiedad collection para definir el nombre de las instancias de recogida de esta clase se persistido a.

Sin embargo, hay un JIRA issue abierto que sugiere agregar una estrategia de nomenclatura conectable para configurar las maneras en que se manejan los nombres de clases, colecciones y propiedades de una manera más global. Siéntase libre de comentar su caso de uso y votarlo.

+1

Gracias, soy consciente de la anotación @Document y probablemente termine usando eso. Básicamente quería externalizar la configuración de la clase real. El problema de JIRA con el que está vinculado está hablando de una estrategia de nomenclatura y aún sugiere usar la anotación para nombres personalizados. – Danish

+1

El atributo 'collection' admite SpEL para que pueda invocar métodos arbitrarios en otros beans Spring para calcular el nombre de la colección, por ejemplo, usando' # {# bean.someMethod (T (su.totalmente calificado.Tipo))} 'si ha registrado un componente como 'bean' que proporciona un método' someMethod (clase tipo) '. –

6

usando la respuesta de Oliver Gierke anterior, trabajando en un proyecto en el que necesito crear colecciones múltiples para una entidad, quería usar los repositorios de primavera y necesitaba especificar la entidad a usar antes de usar el repositorio.

Me las arreglé para modificar el nombre de la colección de repositorio bajo demanda usando este sistema, usando SPeL. Sin embargo, solo puedes trabajar en 1 colección a la vez.

objeto Dominio

@Document(collection = "#{personRepository.getCollectionName()}") 
public class Person{} 

defecto primavera Repositorio:

public interface PersonRepository 
    extends MongoRepository<Person, String>, PersonRepositoryCustom{ 
} 

interfaz personalizada Repositorio:

public interface PersonRepositoryCustom { 
    String getCollectionName(); 

    void setCollectionName(String collectionName); 
} 

aplicación:

public class PersonRepositoryImpl implements PersonRepositoryCustom { 

    private static String collectionName = "Person"; 

    @Override 
    public String getCollectionName() { 
     return collectionName; 
    } 

    @Override 
    public void setCollectionName(String collectionName) { 
     this.collectionName = collectionName; 
    } 
} 

Para usarlo:

@Autowired 
PersonRepository personRepository; 

public void testRetrievePeopleFrom2SeparateCollectionsWithSpringRepo(){ 
     List<Person> people = new ArrayList<>(); 
     personRepository.setCollectionName("collectionA"); 
     people.addAll(personRepository.findAll()); 
     personDocumentRepository.setCollectionName("collectionB"); 
     people.addAll(personRepository.findAll()); 
     Assert.assertEquals(4, people.size()); 
} 

De lo contrario, si es necesario utilizar variables de configuración, tal vez podría usar algo como esto? source

@Value("#{systemProperties['pop3.port'] ?: 25}") 
+0

no han probado esto, y no está muy limpio, pero +1 solo por ser creativo :) – alex

+0

Parece que está guardando información de "contexto" dentro de un repositorio que está potencialmente auto-conectado en varios lugares. Creo que esta solución no es segura para subprocesos. – thanosa75

+0

@ thanosa75 tiene razón, solo estaba reutilizando esa solución y pensaba que tener un repositorio donde siempre proporcionara el nombre de la colección sería mucho más seguro: en lugar de repo.findAll()> repo.findAll ("collectionName"). pero no sé cómo hacerlo elegantemente (en lugar de recrear una clase que reutilice una plantilla de mongo, y establecer siempre el nombre de la colección antes de ejecutar la solicitud) – Jeremie

Cuestiones relacionadas