You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When I have 2 classes, say class A and class B that both have a reference to each other using @reference, things work fine. However if I use "@reference(lazy = true) the code throws an exception on the read of one of the objects.
I am using these dependencies in my gradle project:
compile 'org.mongodb.morphia:morphia:0.1+'
compile 'cglib:cglib:2.+'
compile 'com.thoughtworks.proxytoys:proxytoys:1.+'
Here is sample code that shows the bug (the exception it produces is after the code):
import java.util.Iterator;
import java.util.UUID;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.annotations.Reference;
import com.mongodb.MongoClient;
public class Main
{
public static void main(String[] args) throws Exception
{
Main main = new Main();
main.go();
}
private void go() throws Exception
{
A a = new A(UUID.randomUUID().toString());
B b = new B(UUID.randomUUID().toString());
a.setB(b);
b.setA(a);
MongoClient mongoClient = new MongoClient();
Morphia morphia = new Morphia();
morphia.map(A.class, B.class);
Datastore datastore = morphia.createDatastore(mongoClient, "dbName");
datastore.save(a);
datastore.save(b);
Iterator it = datastore.createQuery(A.class).iterator();
while (it.hasNext())
{
A newA = it.next();
B newB = newA.getB();
System.out.println(newA);
System.out.println(newB);
}
}
}
@Entity(value = "collectionA", noClassnameStored = true)
class A
{
@Id
private String id;
@Reference(lazy = true)
private B b;
private A()
{
}
A(String id)
{
this.id = id;
}
void setB(B b)
{
this.b = b;
}
B getB()
{
return b;
}
}
@Entity(value = "collectionB", noClassnameStored = true)
class B
{
@Id
private String id;
@Reference(lazy = true)
private A a;
private B()
{
}
B(String id)
{
this.id = id;
}
void setA(A a)
{
this.a = a;
}
A getA()
{
return a;
}
}
Here is the stack trace I get:
Apr 22, 2014 1:36:43 PM org.mongodb.morphia.logging.MorphiaLoggerFactory chooseLoggerFactory
INFO: LoggerImplFactory set to org.mongodb.morphia.logging.jdk.JDKLoggerFactory
Exception in thread "main" net.sf.cglib.core.CodeGenerationException: java.lang.NoSuchMethodException-->B$$EnhancerByCGLIB$$db68ebca.()
at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:248)
at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
at net.sf.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:639)
at net.sf.cglib.proxy.Enhancer.firstInstance(Enhancer.java:538)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:225)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:304)
at com.thoughtworks.proxy.factory.CglibProxyFactory.createWithConstructor(CglibProxyFactory.java:150)
at com.thoughtworks.proxy.factory.CglibProxyFactory.createProxy(CglibProxyFactory.java:105)
at com.thoughtworks.proxy.toys.hotswap.HotSwappingInvoker.proxy(HotSwappingInvoker.java:153)
at org.mongodb.morphia.mapping.lazy.CGLibLazyProxyFactory.createProxy(CGLibLazyProxyFactory.java:33)
at org.mongodb.morphia.mapping.ReferenceMapper.createOrReuseProxy(ReferenceMapper.java:379)
at org.mongodb.morphia.mapping.ReferenceMapper.readSingle(ReferenceMapper.java:189)
at org.mongodb.morphia.mapping.ReferenceMapper.fromDBObject(ReferenceMapper.java:176)
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:608)
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:585)
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:296)
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:78)
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:65)
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:60)
at Main.go(Main.java:41)
at Main.main(Main.java:19)
Caused by: java.lang.NoSuchMethodException: B$$EnhancerByCGLIB$$db68ebca.()
at java.lang.Class.getConstructor0(Class.java:2810)
at java.lang.Class.getDeclaredConstructor(Class.java:2053)
at net.sf.cglib.core.ReflectUtils.getConstructor(ReflectUtils.java:244)
... 21 more
The text was updated successfully, but these errors were encountered:
We're a little leery of the circular reference and so there's some debate about if morphia should support such a case. On the other hand, normal loads do have a cache to track already seen entities and so it would seem that it's just not being used for lazy loads. Bumping to post-1.0 for now unless there's strong sentiment otherwise.
When I have 2 classes, say class A and class B that both have a reference to each other using @reference, things work fine. However if I use "@reference(lazy = true) the code throws an exception on the read of one of the objects.
I am using these dependencies in my gradle project:
compile 'org.mongodb.morphia:morphia:0.1+'
compile 'cglib:cglib:2.+'
compile 'com.thoughtworks.proxytoys:proxytoys:1.+'
Here is sample code that shows the bug (the exception it produces is after the code):
Here is the stack trace I get:
The text was updated successfully, but these errors were encountered: