Pregunta

Tengo algunos problemas al usar spring-data-mongodb 1.3.3.RELEASE y Java 1.6.

Mi configuración es un poco complicada porque tengo que lidiar con datos heredados, así que tengo una configuración personalizada. TypeMapper (extensión DefaultMongoTypeMapper) y dos combinaciones diferentes de convertidores de lectura/escritura.Además uso @TypeAlias para configurar el _class información en la base de datos.

Los modelos problemáticos constan de varias listas anidadas, algunas están escritas como

List<DocumentValue>

MyObject puede contener una lista de objetos

List<Object>

que puede contener otro DocumentValue objeto.

Esta configuración parece funcionar, las pruebas unitarias se ejecutan sin ningún problema, el mapeo de objetos se ve bastante bien en el depurador.Mi aplicación es una aplicación web y puedo escribir DocumentValues en una colección, el _class la información está presente.

Mientras no apague el servidor (un Tomcat en mi caso), el mapeo de objetos funciona.Pero cuando reinicio el servidor (inicio una nueva JVM), DocumentValue Los objetos no se asignan correctamente pero se tratan como java.util.Map.El _class La información parece ser ignorada.Supongo que podría haber un problema con mi contexto de mapeo (¿deberían registrarse las entidades de mi modelo mientras se inicia Spring Context?), pero no puedo encontrar la configuración incorrecta.¿Alguien tuvo problemas similares o tiene algunas sugerencias?

¿Fue útil?

Solución

Gracias por su respuesta.Creo que encontré la razón por la cual se ignoró _class.Tienes razón, uso una combinación inusual de TypeMapper.

Déjame mostrarte mi CustomTypeMapper:

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

    }
}

Además del reconocimiento de tipos común, una cosa especial es el constructor en el que se utiliza un MappingContextTypeInformationMapper para utilizar las anotaciones @TypeAlias.

La clave aquí es el MongoMappongContext que se necesita.En el caso no funcional inicialicé CustomTypeMapper como

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

lo cual funcionó pero fue incorrecto, porque la nueva instancia de MongoMappingContext no contenía ninguna información de tipo proporcionada al configurar el atributo del paquete base en

<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>

Desafortunadamente, no pude averiguar dónde se crea MongoMappingContext para poder usarlo como argumento de constructor, así que inventé un bean simple MongoMappingContextProvider que obtiene MongoMappingContext usando @Autowire.

public class MongoMappingContextProvider {

    @Autowired
    private MongoMappingContext mappingContext;

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

}

La configuración de Spring de CustomTypeMapper ahora se ve así

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

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

Esta solución funciona para mí.

Por cierto, para asegurarme de tener todas las informaciones de tipo para todos los beans modelo que uso, agregué @Document a cada bean modelo que persiste, por si acaso;)

Quizás esto sea útil para alguien más con problemas similares.

Saludos, Christoph

Otros consejos

Sospecho que el problema se debe a la combinación inusual de TypeMapper uso y convertidores. Si un implementado manualmente Converter se registra una instancia para un tipo particular, que Converter es responsable de crear un objeto persistente y legible por y desde MongoDB.Esto significa que su instancia de convertidor necesita escribir información de tipo por sí misma.

Si no puede hacerlo funcionar y puede compilar un pequeño proyecto de muestra para reproducir el problema (preferiblemente un caso de prueba para ejecutar), no dude en presentar un ticket en nuestro jira instancia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top