Unable to unmarshall result to class with field of type Map<String, Object>

1,286 views
Skip to first unread message

Giacomo Fornari

unread,
Oct 15, 2014, 10:15:41 AM10/15/14
to jongo...@googlegroups.com
Hi,

when I try to map the result of findOne as a class, I get the error "MarshallingException: Unable to unmarshall result to class models.User from content ...".

My classes which map the document are:

public class User {
   
//... some fields ...
   
private Company company;
   
//... constructor using all fieds ...
   
//... getters and setters for all fields ...
}


public class Company {
   
//... some fields ...
   
private List<Module> modules;
   
//... constructor using all fieds ...
   
//... getters and setters for all fields ...


   
public class Module {
       
private String name;
       
private Date createTime;
       
private Date expireTime;
       
private Map<String, Object> options;


       
//... constructor using all fieds ...
       
//... getters and setters for all fields ...
   
}
}

I think that the problem is the options field, but I'm not sure. Before have added the class Module, everything was ok. After have populated the document that return the findOne method, the exception occurs. So, I can save a User with a Company and a nested Module using the Jongo methods, but I can't retrieve it as User.class.

Any ideas to better explain the problem or to fix it?

Thanks

Benoît GUEROUT

unread,
Oct 15, 2014, 10:32:00 AM10/15/14
to jongo...@googlegroups.com
Hello,

Can you post the full stack trace ?

--
You received this message because you are subscribed to the Google Groups "Jongo" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jongo-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Giacomo Fornari

unread,
Oct 15, 2014, 10:43:51 AM10/15/14
to jongo...@googlegroups.com
This is the full stack trace:

play.api.Application$$anon$1: Execution exception[[MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" : "53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" , "surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" , "telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" , "postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" : "mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" : { "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" , "apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}]]
 at play
.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.2.jar:2.3.2]
 at play
.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at scala
.Option.map(Option.scala:145) [scala-library-2.11.2.jar:na]
Caused by: org.jongo.marshall.MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" : "53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" , "surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" , "telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" , "postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" : "mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" : { "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" , "apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}
 at org
.jongo.marshall.jackson.JacksonEngine.unmarshall(JacksonEngine.java:45) ~[jongo-1.1.jar:na]
 at org
.jongo.ResultHandlerFactory$UnmarshallingResultHandler.map(ResultHandlerFactory.java:43) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.map(FindOne.java:51) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.as(FindOne.java:46) ~[jongo-1.1.jar:na]
 at bdrim
.models.UsersDao.getUser(UsersDao.java:151) ~[classes/:na]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class bdrim.models.Company$Module]: can not instantiate from JSON object (need to add/enable type information?)
 at
[Source: de.undercouch.bson4jackson.io.LittleEndianInputStream@1ceec5a0; pos: 361] (through reference chain: bdrim.models.User["company"]->bdrim.models.Company["modules"])
 at com
.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1065) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:268) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:232) ~[jackson-databind-2.4.1.jar:2.4.1]

Benoît GUEROUT

unread,
Oct 15, 2014, 10:46:58 AM10/15/14
to jongo...@googlegroups.com
According to the stack trace there is a problem when Jackson tries to instanciate a Module: 

Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class bdrim.models.Company$Module]: can not instantiate from JSON object (need to add/enable type information?)

Can you post the Module class definition ?

Giacomo Fornari

unread,
Oct 15, 2014, 11:01:02 AM10/15/14
to jongo...@googlegroups.com
This is the Module class definition. I'm sorry for the indentation, but I can't get a better result. Here a copy on pastebin. 


 public class Module {
 
private String name;
 
private Date createTime;
 
private Date expireTime;
 
private Map<String, Object> options;



 
public Module(String name, Date createTime, Date expireTime, Map<String, Object> options) {
 
super();
 
this.name = name;
 
this.createTime = createTime;
 
this.expireTime = expireTime;
 
this.options = options;
 
}


 
@Override
 
public int hashCode() {
 
final int prime = 31;
 
int result = 1;
 result
= prime * result + getOuterType().hashCode();
 result
= prime * result + ((name == null) ? 0 : name.hashCode());
 
return result;
 
}


 
@Override
 
public boolean equals(Object obj) {
 
if (this == obj)
 
return true;
 
if (obj == null)
 
return false;
 
if (getClass() != obj.getClass())
 
return false;
 
Module other = (Module) obj;
 
if (!getOuterType().equals(other.getOuterType()))
 
return false;
 
if (name == null) {
 
if (other.name != null)
 
return false;
 
} else if (!name.equals(other.name))
 
return false;
 
return true;
 
}


 
public Date getCreateTime() {
 
return createTime;
 
}


 
public Date getExpireTime() {
 
return expireTime;
 
}


 
public String getName() {
 
return name;
 
}


 
public Map<String, Object> getOptions() {
 
return options;
 
}


 
public void setCreateTime(Date createTime) {
 
this.createTime = createTime;
 
}


 
public void setExpireTime(Date expireTime) {
 
this.expireTime = expireTime;
 
}


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


 
public void setOptions(Map<String, Object> options) {
 
this.options = options;
 
}


 
private Company getOuterType() {
 
return Company.this;
 
}
 
}


...

Benoît GUEROUT

unread,
Oct 15, 2014, 11:06:27 AM10/15/14
to jongo...@googlegroups.com
OK,

Jackson can't instanciate a Module because it doesn't know how to invoke the Module constructor.
You can add a default private empty constructor or add @JsonProperty annotation on each constuctor parameters :

public Module(@JsonProperty("name") String name, @JsonProperty("createTime") Date createTime, @JsonProperty("expireTime")Date expireTime, @JsonProperty("options") Map<String, Object> options) {

OR

private Module() {//hidden jackson constructor}


--

Benoît GUEROUT

unread,
Oct 15, 2014, 11:08:09 AM10/15/14
to jongo...@googlegroups.com
You have to add a @JsonCreator annotation too :

@JsonCreator
public Module(@JsonProperty("name") String name, @JsonProperty("createTime") Date createTime, @JsonProperty("expireTime")Date expireTime, @JsonProperty("options") Map<String, Object> options) {

Giacomo Fornari

unread,
Oct 15, 2014, 11:40:44 AM10/15/14
to jongo...@googlegroups.com
I've followed the first solution (the second one with the private constructor doesn't work for me) and the error "No suitable constructor found for type ..." is changed with "Unrecognized Type: [null]". Even if I think that this error does not concern to jongo, I appreciate any suggestion. This is the full stack trace:

play.api.Application$$anon$1: Execution exception[[MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" :"53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" ,"surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" ,"telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" ,"postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" :"mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" :{ "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" ,"apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}]]
 at play
.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.2.jar:2.3.2]
 at play
.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at scala
.Option.map(Option.scala:145) [scala-library-2.11.2.jar:na]
Caused by: org.jongo.marshall.MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" :"53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" ,"surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" ,"telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" ,"postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" :"mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" :{ "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" ,"apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}
 at org
.jongo.marshall.jackson.JacksonEngine.unmarshall(JacksonEngine.java:45) ~[jongo-1.1.jar:na]
 at org
.jongo.ResultHandlerFactory$UnmarshallingResultHandler.map(ResultHandlerFactory.java:43) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.map(FindOne.java:51) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.as(FindOne.java:46) ~[jongo-1.1.jar:na]
 at bdrim
.models.UsersDao.getUser(UsersDao.java:151) ~[classes/:na]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unrecognized Type: [null]
 at com
.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:266) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:241) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:367) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:152) ~[jackson-databind-2.4.1.jar:2.4.1]
Caused by: java.lang.IllegalArgumentException: Unrecognized Type: [null]
 at com
.fasterxml.jackson.databind.type.TypeFactory._constructType(TypeFactory.java:406) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:358) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BasicDeserializerFactory.constructCreatorProperty(BasicDeserializerFactory.java:679) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerConstructors(BasicDeserializerFactory.java:436) ~[jackson-databind-2.4.1.jar:2.4.1]
 at com
.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:325) ~[jackson-databind-2.4.1.jar:2.4.1]

...

Benoît GUEROUT

unread,
Oct 15, 2014, 11:56:09 AM10/15/14
to jongo...@googlegroups.com
I'm not sure about that but it is may be related to the generic <String,Object> on Map named options.
Can replace Object with '?' or something more specific like Option class

--

Giacomo Fornari

unread,
Oct 16, 2014, 6:17:53 AM10/16/14
to jongo...@googlegroups.com
Finally, I solved my problem. Reading again the above posts, I've never mentioned that Module was a nested class in Company. I'm sorry for that.

The solution is put the nested class Module outside Company. With this change, the private constructor in Module like you suggested and the Map<String, Object> work.

Thank you!



Il giorno mercoledì 15 ottobre 2014 17:56:09 UTC+2, Benoît GUEROUT ha scritto:
I'm not sure about that but it is may be related to the generic <String,Object> on Map named options.
Can replace Object with '?' or something more specific like Option class
On Wed, Oct 15, 2014 at 5:40 PM, Giacomo Fornari <fornari...@gmail.com> wrote:
I've followed the first solution (the second one with the private constructor doesn't work for me) and the error "No suitable constructor found for type ..." is changed with "Unrecognized Type: [null]". Even if I think that this error does not concern to jongo, I appreciate any suggestion. This is the full stack trace:

play.api.Application$$anon$1: Execution exception[[MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" :"53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" ,"surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" ,"telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" ,"postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" :"mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" :{ "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" ,"apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}]]
 at play
.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.2.jar:2.3.2]
 at play
.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at play
.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.2.jar:2.3.2]
 at scala
.Option.map(Option.scala:145) [scala-library-2.11.2.jar:na]
Caused by: org.jongo.marshall.MarshallingException: Unable to unmarshall result to class bdrim.models.User from content { "_id" : { "$oid" :"53beb050d10e5ba896d8d912"} , "email" : "xxx...@xxxxx.it" , "name" : "xxxxxx" ,"surname" : "xxxxxx" , "password" : "$2a$10$E4hi2giYm4LnYq5e3TrfheGhsjtydWtl3GR/87.tUIA1Xs8MtY9kS" , "company" : { "name" : "xxxxxx s.r.l." , "vat" : "00000000000" ,"telephoneNumber" : "00000000" , "country" : "Italy" , "city" : "Cxxxxxxx" ,"postalCode" : "xxxx" , "address" : "Via xxxxx 25/c" , "modules" : [ { "name" :"mailchimp" , "createTime" : { "$date" : "2014-10-15T12:19:12.416Z"} , "expireTime" :{ "$date" : "2015-10-15T12:19:12.416Z"} , "options" : { "listid" : "6d7e5ad5b8" ,"apikey" : "9fe7bcfxxxxxxxxxxxxxxxxxxxxxc9ea-us9"}}]} , "role" : "Super Administrator" , "idShop" : "Shop2"}
 at org
.jongo.marshall.jackson.JacksonEngine.unmarshall(JacksonEngine.java:45) ~[jongo-1.1.jar:na]
 at org
.jongo.ResultHandlerFactory$UnmarshallingResultHandler.map(ResultHandlerFactory.java:43) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.map(FindOne.java:51) ~[jongo-1.1.jar:na]
 at org
.jongo.FindOne.as(FindOne.java:46) ~[jongo-1.1.jar:na]
 at bdrim
.models.UsersDao.getUser(UsersDao.java:151) ~[classes/:na]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unrecognized Type: [null]
 at com
.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:266) ~[jackson-databind-2.4.1.jar:2.4.1]

 at com
.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:241) ~[jackson-databind-2.4.<span style="color:#06
...
Reply all
Reply to author
Forward
0 new messages