2015-01-19 8 views
6

Mit zwei Arten von Unternehmen, die zu zwei Java-Klassen in der Einzel MongoDB Sammlung abgebildet werden:Spring Data MongoDB Repositorys nicht implementieren Vererbung richtig

@Document 
public class Superclass { ... } 

@Document(collection = "superclass") 
public class Subclass extends Superclass { ... } 

und zwei Endlager für dieses Unternehmen:

public interface SuperclassRepository extends MongoRepository<Superclass, String> {} 
public interface SubclassRepository extends MongoRepository<Subclass, String> {} 

MongoRepositories nicht die Vererbung der Entitäten korrekt behandeln. Bei der Abfrage aller Objekte (zB SubclassRepository.findAll()) enthält die Ergebnismenge Superclass Objekte, die instanziert (oder zumindest versucht wurden instanziiert zu sein) mit Nullwerten für Felder, die Teil der Subclass sind, aber nicht Teil der Superclass sind .

Das erwartete Ergebnis wäre, dass SubclassRepository nur Subclass Objekte zurück, während SuperclassRepositorySuperclass und Subclass Objekte zurückgeben sollte. Dies funktioniert in Spring Data JPA.

Hat jemand diesen Fehler gefunden und hat eine Lösung, wie man ihn beheben kann?

+0

ich habe ein [ticket] erstellt (https://jira.spring.io/brows e/DATAMONGO-1142) und die [pull request] (https://github.com/spring-projects/spring-data-mongodb/pull/266) für diesen Fehler. –

Antwort

3

Ich begegne dem gleichen Problem.

Werfen Sie einen Blick auf den Quellcode und zu meiner Überraschung ist es irgendwie nicht implementiert. Es fügt den Auflistungsnamen und die Entitätsklasse hinzu, fügt sie jedoch nicht in die finale Abfrage der Eigenschaft _class ein. Und nachdem ich einen Blick darauf geworfen hatte, erkannte ich, dass Mongo die SubClass1 oder Subclass2 von SuperClass kannte. So überschreiben ich die SimpleMongoRepository Klasse gerade und meine eigene Fabrik erstellen, die diese Klasse SimpleMongoRepository anstelle des Standard setzen

Hier ist, was ich hinzugefügt:

public MySimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) { 

    Assert.notNull(mongoOperations); 
    Assert.notNull(metadata); 

    this.entityInformation = metadata; 
    this.mongoOperations = mongoOperations; 
    Reflections reflections = new Reflections("com.cre8techlabs.entity"); 
    Set<String> subTypes = reflections.getSubTypesOf(entityInformation.getJavaType()).stream().map(Class::getName).collect(Collectors.toSet()); 
    subTypes.add(entityInformation.getJavaType().getName()); 
    this.baseClassQuery = Criteria.where("_class").in(subTypes.toArray()); 
} 

Und hier ein Beispiel für die Umsetzung eines

finden
public T findOne(ID id) { 
    Assert.notNull(id, "The given id must not be null!"); 
    Query q = getIdQuery(id).addCriteria(baseClassQuery); 

    return mongoOperations.findOne(q, entityInformation.getJavaType(), entityInformation.getCollectionName()); 
} 

es funktioniert für mich, bin ich nur Angst, dass es etwas länger dauern

+1

Das Ideal wäre QueryMapper zu ändern, aber es bedeutet, das MongoTemplate zu ändern –

Verwandte Themen