MorphiaOrg / MorphiaOrg/morphia

Regression when querying objects with cyclic references

Open
#1,658 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
1.7k
Forks
449
Avg merge
7m
Merged PRs (30d)
10

Description

Describe the bug
When you have entites with cyclic references in your model, querying them results in an exception with a huge stack trace. This seems to be due to an endless recursion when trying to resolve the reference.

To Reproduce
Steps to reproduce the behavior:

  1. Create a model with two entities referencing each other (e.g. a project referencing issues with the issues having a back reference to their project). See attached files for an example.
  2. Insert two objects with cyclic references.
  3. Query one of the objects and observe the exception in the attached log file.

Expected behavior
Successfully resolve the references like in the equivalent code in 1.6.1.

Please complete the following information:

  • Server Version: 5.0.2
  • Driver Version: 4.2.2
  • Morphia Version: 2.2.2

Additional context
stacktrace.log

App.java

package test;

import com.mongodb.client.MongoClients;

import org.bson.types.ObjectId;

import dev.morphia.Morphia;

public class App {
    public static void main(String[] args) {
        var mongoClient = MongoClients.create("...");

        var ds = Morphia.createDatastore(mongoClient, "cyclic-test");
        ds.getMapper().map(E1.class, E2.class);

        var e1 = new E1(new ObjectId(), "Stuff");
        var e2 = new E2(new ObjectId(), e1);
        e1.setRelated(e2);

        ds.save(e1);
        ds.save(e2);

        var ds2 = Morphia.createDatastore(mongoClient, "reference-test");
        var e1returned = ds2.find(E1.class).iterator().next();

        System.out.println("returned " + e1returned.getName() + ", " + e1returned.getRelated());
    }
}

E1.java

package test;

import org.bson.types.ObjectId;

import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Reference;

@Entity
public class E1 {

    public E1() {
    }

    public E1(ObjectId id, String name) {
        this.setId(id);
        this.setName(name);
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public E2 getRelated() {
        return related;
    }

    public void setRelated(E2 related) {
        this.related = related;
    }

    @Id
    private ObjectId id;
    private String name;

    @Reference(idOnly = true, ignoreMissing = true)
    private E2 related;
}

E2.java

package test;

import org.bson.types.ObjectId;

import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Reference;

@Entity
public class E2 {

    public E2() {

    }

    public E2(ObjectId id, E1 related) {
        this.setId(id);
        this.setRelated(related);
    }

    public E1 getRelated() {
        return related;
    }

    public void setRelated(E1 related) {
        this.related = related;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    @Id
    private ObjectId id;

    @Reference(idOnly = true, ignoreMissing = true)
    private E1 related;
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the regression using the App.java example with the E1.java and E2.java cyclic-reference models, then inspect the attached stacktrace.log to identify where reference resolution recurses. The fix is complete when querying the cyclic objects succeeds without the huge stack trace, matching the behavior described for version 1.6.1.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, mongodb
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.