MorphiaOrg / morphia

MongoDB object-document mapper in Java based on https://github.com/mongodb/mongo-java-driver
Apache License 2.0
1.65k stars 456 forks source link

Can't use List<Object> in my document and can't query inside of it #1521

Closed mfalcier closed 3 years ago

mfalcier commented 3 years ago

Describe the bug I've created an entity Employee, and a Foo class. The entity Employee contains an attribute with a list of Foos, Foo is not a document.

@Entity("employees")
data class Employee (
    @Id
    var _id: String? = ObjectId().toString(),
    @Indexed
    var name: String? = null,
    @Indexed
    var foos: MutableList<Foo>? = mutableListOf()
)
data class Foo (
        @Indexed
        var test: String? = null
)

When I try to save it, I'm encountering an org.bson.codecs.configuration.CodecConfigurationException for the Foo class saying: "Can't find a codec for class com.foo.Foo.".

I kinda avoided this issue connecting to mongo this way:

val connectionString = ConnectionString("mongodb://127.0.0.1:27017")
val pojoCodecRegistry: CodecRegistry = CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
val codecRegistry: CodecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry)
val clientSettings = MongoClientSettings.builder()
        .applyConnectionString(connectionString)
        .codecRegistry(codecRegistry)
        .build()

val mongoClient = MongoClients.create(clientSettings)
val dataStore = Morphia.createDatastore(mongoClient, "morphia_test")

After this, I'm getting another error, since I want to query my document this way:

val result = dataStore.find(Employee::class.java)
                .filter(
                        eq("foos.test", "test1")
                )

The error is a dev.morphia.query.ValidationException saying: "Could not resolve path 'foos.test' against 'com.foo.Employee'.".

From here, I got stucked 2 days, and I couldn't find a workaround on it. As suggested here, I opened an issue.

To Reproduce See the attached reproducer. reproducer.zip

Expected behavior Not getting a CodecConfigurationException, since I was doing this on previous version of Morphia (1.3.2). Not getting a ValidationException, since I was doing this on previous version of Morphia (1.3.2) and on daily basis on MongoDB Compass.

DefiantCatgirl commented 3 years ago

For the ValidationException, I suspect that @Embedded may be required on Foo.

However this is not a solution for the same ValidationException problem I'm having, since I cannot use @Embedded for embedded classes where I have to have an @Id field (as they are also used as separate entities)...

mfalcier commented 3 years ago

I've tried everything @DefiantCatgirl , without success :( That is going to fix the validation, but it always result into an empty query result.

evanchooly commented 3 years ago

@Embedded is definitely required. fwiw, you don't need to configure any codecs specifically like you're doing. Morphia will take care of that for you. I'll look in to the query bits today.

evanchooly commented 3 years ago

Running your reproducer, if I put @Embedded on Foo neither test fails and works as expected.

mfalcier commented 3 years ago

@evanchooly does It return a result? Because when I've tried It before, but the query didn't worked. I'll try it later and let you know my results. Thanks.

evanchooly commented 3 years ago

Yes. The query returns returns 1 item as expected.

mfalcier commented 3 years ago

Ok I've tried to put the @Embedded annotation on Foo and it worken on the first test. On the second it's not working, but I guess it's because I'm changin things on the codecs. I've tried the annotation before, but probably only after cheating out with the codecs: since that annotation wasn't required in the past, I haven't thought it would solve the first CodecConfigurationException. Thanks @evanchooly for your fast reply, and I guess the issue is solved.

evanchooly commented 3 years ago

Use the Datastore from the test base. It's properly configured already.. but it worked with both for me.