Skip to content

skip query returns the same Snapshot with MongoDB #1391

@antongub

Description

@antongub

Clear description of my expectations versus reality
When I use the QueryBuilder skip method with two consecutive parameters (e.g. first with '1' and then with '2'), I expect to get different results each time I execute the query in my Javers find method, but this is not happening.

Steps To Reproduce
I have a **runnable test case ** which isolates the bug and allows Javers Core Team to easily reproduce it. I have pushed this test case to my fork of this repository:

https://github.com/antongub/javers/blob/master/javers-persistence-mongo/src/test/groovy/org/javers/repository/mongo/cases/SkipQueryTest.groovy

import com.mongodb.client.MongoDatabase
import org.javers.core.JaversBuilder
import org.javers.core.metamodel.annotation.Entity
import org.javers.core.metamodel.annotation.Id
import org.javers.core.metamodel.annotation.ValueObject
import org.javers.repository.jql.QueryBuilder
import org.javers.repository.mongo.BaseMongoTest
import org.javers.repository.mongo.MongoRepository


class SkipQueryTest extends BaseMongoTest {

    @Entity
    class Customer {
        @Id
        String id

        Configuration conf = new Configuration()

        Customer(id) {
            this.id = id
        }
    }

    @ValueObject
    class Configuration {
        String currency = "EUR"
    }


    def "should return two different snapshot ids"() {
        given:
        Customer customer1 = new Customer("1")
        Customer customer2 = new Customer("2")

        MongoDatabase mongo = mongoClient.getDatabase("test")
        def repo = new MongoRepository(mongo)
        def javers = JaversBuilder.javers().registerJaversRepository(repo).build()

        when:
        javers.commit("author", customer1)
        javers.commit("author", customer2)

        then:
        def query1 = QueryBuilder.anyDomainObject().limit(1).skip(0).build()
        def query2 = QueryBuilder.anyDomainObject().limit(1).skip(1).build()
        def snapshot1Id = javers.findSnapshots(query1)[0].globalId
        def snapshot2Id = javers.findSnapshots(query2)[0].globalId
        snapshot1Id != snapshot2Id
    }
}

result:

Condition not satisfied:

snapshot1Id != snapshot2Id
|           |  |
|           |  ...SkipQueryTest$Customer/2#conf
|           false
...SkipQueryTest$Customer/2#conf

Condition not satisfied:

snapshot1Id != snapshot2Id
|           |  |
|           |  ...SkipQueryTest$Customer/2#conf
|           false
...SkipQueryTest$Customer/2#conf

	at org.javers.repository.mongo.cases.SkipQueryTest.should return two different snapshot ids(SkipQueryTest.groovy:55)

Javers' Version
7.4.5

Additional context
The issue only occurs when an entity contains at least one ValueObject. This is because the entity along with its ValueObjects all share the same commit_id and the snapshots are only sorted by the commit_id (or commit_date_instant if instructed). Therefore, the fix involves adding an additional sorting criterion that differentiates each entry else MongoDB's natural (default) ordering takes effect.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions