Frage

Ich habe einige Probleme bei der Verwendung von spring-data-mongodb 1.3.3.RELEASE und Java 1.6.

Meine Einrichtung ist etwas kompliziert, da ich mit Altdaten umgehen muss, also habe ich eine benutzerdefinierte TypeMapper (erweiternd DefaultMongoTypeMapper) und zwei verschiedene Lese-/Schreibkonverter-Kombinationen.Zusätzlich verwende ich @TypeAlias zum Einstellen der _class Informationen in der Datenbank.

Die problematischen Modelle bestehen aus mehreren verschachtelten Listen, von denen einige typisiert sind

List<DocumentValue>

MyObject kann eine Objektliste enthalten

List<Object>

die eine andere enthalten kann DocumentValue Objekt.

Dieses Setup scheint zu funktionieren, Unit-Tests laufen problemlos, die Objektzuordnung sieht im Debugger ganz gut aus.Meine Bewerbung ist eine Webanwendung und ich kann schreiben DocumentValues in eine Sammlung, die _class Informationen vorhanden sind.

Solange ich den Server (in meinem Fall einen Tomcat) nicht herunterfahre, funktioniert die Objektzuordnung.Aber wenn ich den Server neu starte (eine neue JVM starte), DocumentValue Objekte werden nicht korrekt zugeordnet, aber als behandelt java.util.Map.Der _class Informationen scheinen ignoriert zu werden.Ich gehe davon aus, dass es ein Problem mit meinem Zuordnungskontext gibt (sollten meine Modellentitäten beim Start von Spring Context registriert werden?), aber ich kann die Fehlkonfiguration nicht finden.Hatte jemand ähnliche Probleme oder hat er Vorschläge?

War es hilfreich?

Lösung

Danke für deine Antwort.Ich glaube, ich habe den Grund gefunden, warum _class ignoriert wurde.Sie haben Recht, ich verwende eine ungewöhnliche Kombination von TypeMapper.

Lassen Sie mich Ihnen meinen CustomTypeMapper zeigen:

public class CustomTypeMapper extends DefaultMongoTypeMapper {

    public CustomTypeMapper (MongoMappingContext mappingContext) {

        super(DEFAULT_TYPE_KEY,
                Arrays.asList(new MappingContextTypeInformationMapper(
                        mappingContext)));
    }

    @Override
    public <T> TypeInformation<? extends T> readType(DBObject source,
            TypeInformation<T> basicType) {

        // do some custom recognition

                // or just to the common type mapping
        return super.readType(source, basicType);

    }
}

Eine Besonderheit neben der allgemeinen Typerkennung ist der Konstruktor, in dem ein MappingContextTypeInformationMapper zur Verwendung der @TypeAlias-Annotationen verwendet wird.

Der Schlüssel hier ist der benötigte MongoMappongContext.Im nicht funktionsfähigen Fall habe ich den CustomTypeMapper wie initialisiert

<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
    <constructor-arg name="mappingContext">
        <bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
    </constructor-arg>
</bean>

was funktionierte, aber falsch war, da die neue Instanz von MongoMappingContext keine TypeInformation enthielt, die durch das Festlegen des Basispaketattributs bereitgestellt wurde

<mongo:mapping-converter id="customMappingConverter" db-factory-ref="mongoDbFactory"
        type-mapper-ref="customTypeMapper" base-package="de.flexguse.model" >

    <mongo:custom-converters>
            ... some custom converters ...
    </mongo:custom-converters>

</mongo:mapping-converter>

Leider konnte ich nicht herausfinden, wo der MongoMappingContext erstellt wird, um ihn als Konstruktorargument verwenden zu können, also habe ich eine einfache Bean MongoMappingContextProvider erfunden, die den MongoMappingContext mithilfe von @Autowire abruft

public class MongoMappingContextProvider {

    @Autowired
    private MongoMappingContext mappingContext;

    /**
     * @return the mappingContext
     */
    public MongoMappingContext getMappingContext() {
        return mappingContext;
    }

}

Die Spring-Konfiguration des CustomTypeMapper sieht nun so aus

<bean id="mongoMappingContextProvider" class="de.flexguse.repository.MongoMappingContextProvider" />

<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
    <constructor-arg name="mappingContext" value="#{mongoMappingContextProvider.mappingContext}" />
</bean>

Diese Lösung funktioniert für mich.

Um sicherzugehen, dass alle Typinformationen für alle von mir verwendeten Modell-Beans vorhanden sind, habe ich @Document zu jedem Modell-Bean hinzugefügt, das beibehalten wird – nur für den Fall ;)

Vielleicht ist das für jemand anderen mit ähnlichen Problemen hilfreich.

Grüße, Christoph

Andere Tipps

Ich vermute, dass das Problem auf die ungewöhnliche Kombination zurückzuführen ist TypeMapper Verwendung und Konverter. Wenn eine manuell implementierte Converter Instanz für einen bestimmten Typ registriert ist, das Converter ist dafür verantwortlich, ein Objekt zu erstellen, das von und aus MongoDB dauerhaft und lesbar ist.Das bedeutet, dass Ihre Konverterinstanz selbst Typinformationen schreiben muss.

Wenn Sie es nicht zum Laufen bringen und ein kleines Beispielprojekt kompilieren können, um das Problem zu reproduzieren (vorzugsweise einen Testfall zur Ausführung), können Sie gerne ein Ticket bei uns einreichen JIRA Beispiel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top