New issue 245 by whiting....@gmail.com: Embedded objects in embedded list
giving exeption
http://code.google.com/p/morphia/issues/detail?id=245
Morphia Version: 0.99
detailMessage "java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String
cannot be cast to com.mongodb.DBObject" (id=187)
I added @Entity to the List to in the parent object:
@Embedded
private List<ContentFieldDescriptor> fields = new
ArrayList<ContentFieldDescriptor>();
and the Object definition:
@Embedded
public class ContentFieldDescriptor implements Serializable
The output of the objects:
"fields" : [
{
"dataType" : "File",
"fileName" : "IMG_0199.JPG",
"mimeType" : "image/jpeg",
"name" : "File"
},
{
"dataType" : "Text",
"payLoad" : "<TEXTFORMAT LEADING=\"2\"><P ALIGN=\"LEFT\"><FONT
FACE=\"Arial\" SIZE=\"12\" COLOR=\"#000000\" LETTERSPACING=\"0\"
KERNING=\"0\">ab</FONT></P></TEXTFORMAT>",
"name" : "Description"
}
Can you please include the class def for ContentFieldDescriptor (and any
base classes) and a full stack trace?
There is no base class (other than Object). The attributes are public as i
will be serializing the object to AMF post database retrieval - so please
excuse the public get/set and the public attribute.
Thanks!
CLASS DEF
------------------------------------------------------------------------------------
import java.io.Serializable;
import com.google.code.morphia.annotations.Embedded;
@Embedded
public class ContentFieldDescriptor implements Serializable{
public String dataType;
public String fileName;
public String mimeType;
public Object payLoad;
// name of the field...
public String name;
public ContentFieldDescriptor()
{
super();
}
public String getMimeType()
{
return this.mimeType;
}
public void setMimeType(String mimeType)
{
this.mimeType = mimeType;
}
public String getFileName()
{
return this.fileName;
}
public ContentFieldDescriptor setFileName(String fileName)
{
this.fileName = fileName;
return this;
}
public String getDataType()
{
return this.dataType;
}
public ContentFieldDescriptor setDataType(String dataType)
{
this.dataType = dataType;
return this;
}
public Object getPayLoad()
{
return this.payLoad;
}
public ContentFieldDescriptor setPayLoad(Object payLoad)
{
this.payLoad = payLoad;
return this;
}
public String getName()
{
return this.name;
}
public ContentFieldDescriptor setName(String name)
{
this.name = name;
return this;
}
}
STACK TRACE
-----------------------------------------------------------------
java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.ClassCastException: java.lang.String cannot be cast to
com.mongodb.DBObject
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:483)
at com.google.code.morphia.mapping.Mapper.fromDBObject(Mapper.java:267)
at
com.google.code.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:53)
at
com.google.code.morphia.query.MorphiaIterator.next(MorphiaIterator.java:48)
at com.google.code.morphia.query.QueryImpl.asList(QueryImpl.java:234)
at
com.soapbox.content.domain.DomainFolderDAO.getContent(DomainFolderDAO.java:203)
at
com.soapbox.content.ContentManager.getContentForDomain(ContentManager.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:421)
at
flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
at
flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1503)
at
flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:884)
at
flex.messaging.endpoints.AbstractEndpoint$$FastClassByCGLIB$$1a3ef066.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at
org.springframework.flex.core.MessageInterceptionAdvice.invoke(MessageInterceptionAdvice.java:59)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.Cglib2AopProxy$FixedChainStaticTargetInterceptor.intercept(Cglib2AopProxy.java:576)
at
flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$fd6b49f.serviceMessage(<generated>)
at
flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)
at
flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
at
flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
at
flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:278)
at
flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$fd6b49f.service(<generated>)
at
org.springframework.flex.servlet.MessageBrokerHandlerAdapter.handle(MessageBrokerHandlerAdapter.java:101)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:824)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:769)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613)
at
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:536)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String
cannot be cast to com.mongodb.DBObject
at
com.google.code.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:146)
at com.google.code.morphia.mapping.Mapper.readMappedField(Mapper.java:499)
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:480)
... 50 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.ClassCastException: java.lang.String cannot be cast to
com.mongodb.DBObject
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:483)
at
com.google.code.morphia.mapping.EmbeddedMapper.readMapOrCollectionOrEntity(EmbeddedMapper.java:231)
at
com.google.code.morphia.mapping.EmbeddedMapper.readCollection(EmbeddedMapper.java:175)
at
com.google.code.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:119)
... 52 more
Caused by: java.lang.RuntimeException: java.lang.ClassCastException:
java.lang.String cannot be cast to com.mongodb.DBObject
at
com.google.code.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:146)
at com.google.code.morphia.mapping.Mapper.readMappedField(Mapper.java:503)
at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:480)
... 55 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to
com.mongodb.DBObject
at
com.google.code.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:136)
... 57 more
I downloaded the morphia source and ran the web app in debug mode from
eclipse. The exception comes on one of the fields - payLoad - whose type is
Object. The value is a string. I marked it as object to allow it to be
highly dynamic from the client side (actionscript). Hence the cast
exception.
{
"dataType" : "Text",
"payLoad" : "<TEXTFORMAT LEADING=\"2\"><P ALIGN=\"LEFT\"><FONT
FACE=\"Arial\" SIZE=\"12\" COLOR=\"#000000\" LETTERSPACING=\"0\"
KERNING=\"0\">ab</FONT></P></TEXTFORMAT>",
"name" : "Description"
}
Within the Java API String does extend Object. is this not do-able from
Morphia? I understand the need to eventually boil fields down to a specific
type - is there anything that can be done? Woud using the Groovy drivers
allow for less strict handling of the type to value mapping?
Whoops - there is no groovy extension. I was probably thinking of Spring.
Comment #5 on issue 245 by scotthernandez: Embedded objects in embedded
list giving exeption
http://code.google.com/p/morphia/issues/detail?id=245
You need to annotate that fields as @Property and it will fix it. Right now
it is not, and I'm not sure it can ever be, smart enough to dynamically
adjust from the default @Embedded and the simple types mappers.
Basically you need to give it a hint that the type is a basic one, not a
nested (embedded) document.
Let me know if doesn't work and we can re-open the case.