google-code-export / morphia

Automatically exported from code.google.com/p/morphia
1 stars 0 forks source link

Lazy OneToMany reverse mapping #357

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What version are you using? (Morphia/Driver/MongoDB)

Morphia: 0.99, Mongo Driver: 2.6.5, MongoDB: 2.0.0

Hi everyone,

I am relatively new to mongo - and morphia of course, but I'm quite fascinated 
by the schema-less, document database concept. I tried morphia recently and I 
would like to contribute to this ambitious project.
I've been using JPA (mainly hibernate) for quite some time, so inevitably I 
cannot avoid the comparison between morphia and JPA.

One thing that I would like to have in morphia is the OneToMany association of 
a parent entity towards its children, using reverse mapping. This would allow 
morphia to store only the child to parent reference inside the child 
collection, without having to store the children references inside the parent 
collection. When a parent entity is loaded from the db a lazy collection with 
children is prepared. When the collection of children is first accessed (by 
requesting size() for example) the lazy collection is filled with proxy 
references of child entities. Finally, each child is actually fetched upon the 
first usage. The benefit of this functionality is to avoid multiple save 
operations on the parent entity, after adding a child.

Actually what I have implemented so far is the following:

1) A custom proxy factory that provides a utility method to create the lazy 
collection on the parent entity: (Only List is supported for now)

public <T extends Collection> T createListProxy(Object parent, String 
mappedByFieldName, final T listToProxy, final Class referenceObjClass, final 
boolean ignoreMissing, final DatastoreProvider p) { ... }

The above snippet follows the principles of morphia's CGLibLazyProxyFactory 
class.

2) A custom implementation of the ProxiedEntityReferenceList interface similar 
to SerializableCollectionObjectReference except that it requires the parent 
entity and the child field name (mappedBy attribute) that holds the reference 
to this particular parent.

3) An EntityInterceptor implementation that uses the postLoad method to replace 
the actual children collection with the proxy list.

4) The parent class:

@Entity
public class Parent {
    @Id
    private ObjectId id;

    @Reference(lazy=true)
    @NotSaved
    //@OneToMany(mappedBy="parent")
    private List<Child> children;
...
}

5) The child class:

@Entity
public class Child {
    @Id
    private ObjectId id;

    @Reference(lazy=true)
    private Parent parent;
...
}

As a next step I was thinking to create a custom annotation @OneToMany or 
update the existing @Reference annotation and process it inside the 
ReferenceMapper class to achieve the above functionality.

If you find this issue interesting I could prepare a patch and submit it.

Best regards,
Nick

PS: What is the procedure to participate in the project?

Original issue reported on code.google.com by nikfoun...@gmail.com on 8 Dec 2011 at 9:22

GoogleCodeExporter commented 9 years ago
To participate you can do many different things. In general creating issues is 
not a good way to discuss things. The list is much better for this -- 
http://groups.google.com/group/morphia

Patches are always welcome, but we like to get a good deal of community support 
before adding features for example.

I'd suggest posting to the list to discuss this feature and get 
support/consensus.

Original comment by scotthernandez on 9 Dec 2011 at 2:11