0

I found this post where it is discussed if references between documents should be established. I want to annotate my Java class so that references within JSON documents are created:

{
    "id": "3",
    "bs": [
        {
            "name": "abc"
        },
        {
            "name": "def",
            "preconditions": ["abc"]
        },
        {
            "name": "ghi",
            "preconditions":  ["abc"]
        }
    ]
}

Here the objects of the list preconditions have references to objects of the list bs. Is that possible in MongoDB? How is it called (I was unable to find any information using the keywords "embedded reference" and "reference within documents".) How would a solution look like with morphia?

EDIT:I know the reference annotation but it seems to refernce to anoter collection and not to a list of objects in the same document. I just want to ensure, that the serialized java objects are deserialized correctly (both attributes should become references to the same object).

EDIT II: To clarify my problem I provide the code which I used for testing:

Class A

@Entity("MyAs")
public class A {
    @Id
    public String name;

    @Embedded
    public List<B> bs=new LinkedList<B>();
}

Class B

public class B {
    @Id
    public String bName;

    public List<B> preconditions=new LinkedList<B>(); 
}

In my main method I do the following:

final Datastore datastore = morphia.createDatastore(new MongoClient(), 
"Test");
B b1=new B();
b1.bName="b1";

B b2=new B();
b2.bName="b2";

b1.preconditions.add(b2);

List<B> bs=new LinkedList<B>();
bs.add(b1);
bs.add(b2);

A a1=new A();
a1.name="mya1";
a1.bs=bs;

datastore.save(a1);

A myA=datastore.get(A.class,"mya1");
System.out.println(myA.bs.get(0).preconditions.get(0));
System.out.println(myA.bs.get(0).preconditions.get(0).hashCode()+" --"  +myA.bs.get(0).preconditions.get(0).bName);
System.out.println(myA.bs.get(1));
System.out.println(myA.bs.get(1).hashCode() +" --" +  myA.bs.get(1).bName);

This leads to the following structure in Mongo DB Compass (obviously, no reference is created): enter image description here

If the document is deserialized then (with datastore.get), obviously two separate objects are created for b2 (outputs of System.out.println):

mongotest.B@78b729e6
2025269734 --b2
mongotest.B@6b4a4e18
1800031768 --b2

I want to have a structure where the b2 object in preconditions references to the b2 object in bs!

If I do datastore.get(A.class,"mya1"); I want to have the same structure which I used for the serialization: a single B object which is referenced in the bs list and in the preconditions..

user3579222
  • 1,103
  • 11
  • 28
  • How are you serlializing it? There are going to be 2 B objects because that's how you've modeled it. in the database, they'll still be nested documents inside your A document. With the above code, how does it look in the database? Morphia doesn't require @Id annotations for embedded documents but you have them and that might be leading to some confusion for you. – evanchooly Mar 13 '19 at 21:35
  • Thank you for your effort; I updated my post: I want to annotate my Java code so that the reference in the JSON object is created. When I deserialize the JSON to Java I want to have a single B object which is referenced in the preconditions list as well as in the bs list (currently I get two B objects after deserialization, but I only refered to a single B object when I do the serialization to JSON) – user3579222 Mar 14 '19 at 06:28

2 Answers2

2

To create that structure, you'd simply have a List<B> on your entity and annotate that field with @Embedded. See here for a bit more documentation.

evanchooly
  • 6,102
  • 1
  • 16
  • 23
0

I deleted my MonogDB collection and retried to run my example: Now it seems to work. The b in preconditions referes to the the object in the bs array. The embedded annotation is required!

user3579222
  • 1,103
  • 11
  • 28