2015-01-19 9 views
6

Posiadanie dwóch rodzajów jednostek, które są mapowane do dwóch klas Javy w jednej kolekcji MongoDB:Wiosna danych MongoDB Repozytoria nie implementują dziedziczenie poprawnie

@Document 
public class Superclass { ... } 

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

i dwa repozytoria dla tych podmiotów:

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

MongoRepositories nie obsługuje poprawnie dziedziczenia obiektów. Podczas sprawdzania dla wszystkich obiektów Subclass (np. SubclassRepository.findAll()) zestaw wyników zawiera obiekty Superclass, które są tworzone (lub przynajmniej próbowano je utworzyć) z wartościami pustymi dla pól, które są częścią Subclass, ale nie są częścią Superclass .

Oczekiwany wynik będzie, że SubclassRepository powinien zwrócić tylko Subclass obiektów, natomiast SuperclassRepository powinien powrócić Superclass i Subclass obiektów. Działa to w Spring Data JPA.

Czy ktoś napotkał ten błąd i ma rozwiązanie tego problemu?

+0

Stworzyłem [bilet] (https://jira.spring.io/brows e/DATAMONGO-1142) i [żądanie pobrania] (https://github.com/spring-projects/spring-data-mongodb/pull/266) dla tego błędu. –

Odpowiedz

3

Występuje ten sam problem.

Spójrz na kod źródłowy i ku mojemu zaskoczeniu jest to rodzaj nie zaimplementowany. Dodaje nazwę kolekcji i klasę encji, ale nie dodaje do ostatecznego zapytania właściwości _class. I po obejrzeniu tego zdałem sobie sprawę, że jak Mongo będzie wiedział, że SubClass1 lub Subclass2 pochodzą z SuperClass. Więc po prostu zastąpić klasę SimpleMongoRepository i stworzyć własną fabrykę, która umieścić tej klasy zamiast domyślnego SimpleMongoRepository

Oto co I dodaje:

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()); 
} 

I tu przykład realizacji a find

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()); 
} 

to działa na mnie, jestem po prostu boi się, że to trochę dłużej

+1

Idealnym rozwiązaniem byłoby zmiana QueryMapper, ale będzie to oznaczać zmianę MongoTemplate –

Powiązane problemy