findAll fails after play morphia is reinitialised

2019-09-01 18:53发布

I have the following class which is persisted into a mongodb using morphia in a play! application. The class resides in a module which is a dependency of another play! application.

Its configuration is read from a file and persisted into the db on initial load (if its not already in the db) and then subsequent requests use the db version.

@Entity
public class Page extends Model {

    @Id
    public Long navigationId;

    // etc ...
}

The initial load and subsequent query access works ok and i can see the page in mongo:

> db.Page.find({_id:20000})
{ "_id" : NumberLong(20000), "className" : "models.Page" etc }

However if i restart play! or make a code change that results in Morphia being reinitialised (MorphiaPlugin-1.2.4> initialized appears in the logs) i get the following stack trace:

Caused by: java.lang.RuntimeException: java.lang.RuntimeException: com.google.code.morphia.mapping.MappingException: Error setting value from converter (LongConverter) for models.Page.navigationId to 20000
    at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:487)
    at com.google.code.morphia.mapping.Mapper.fromDBObject(Mapper.java:267)
    at com.google.code.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:66)
    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:255)
    at play.modules.morphia.Model$MorphiaQuery.asList(Model.java:1067)
    at models.Page.findAll(Page.java)
    at plugins.PageConfigLoadPlugin.loadPersistedPages(PageConfigLoadPlugin.java:62)
    at plugins.PageConfigLoadPlugin.onApplicationStart(PageConfigLoadPlugin.java:51)
    at play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:425)
    at play.Play.start(Play.java:495)
    ... 3 more
Caused by: java.lang.RuntimeException: com.google.code.morphia.mapping.MappingException: Error setting value from converter (LongConverter) for models.Page.navigationId to 20000
    at com.google.code.morphia.mapping.ValueMapper.fromDBObject(ValueMapper.java:27)
    at com.google.code.morphia.mapping.Mapper.readMappedField(Mapper.java:501)
    at com.google.code.morphia.mapping.Mapper.fromDb(Mapper.java:484)
    ... 14 more
Caused by: com.google.code.morphia.mapping.MappingException: Error setting value from converter (LongConverter) for models.Page.navigationId to 20000
    at com.google.code.morphia.converters.DefaultConverters.fromDBObject(DefaultConverters.java:133)
    at com.google.code.morphia.mapping.ValueMapper.fromDBObject(ValueMapper.java:25)
    ... 16 more

If i drop the Collection from mongodb using the command line i can again load and query the Page obejct successfully from my play! web application

> db.Page.drop()
true

As I mentioned, this class is in a module. This problem only happens in one application that the module is a dependency of. The other demo application works fine.

any suggestions?

1条回答
太酷不给撩
2楼-- · 2019-09-01 19:05

Does the dependent module have another alternate declaration of the Page or Model classes?

From the top of the stack trace, ("com.google.code.morphia.mapping.MappingException: Error setting value from converter (LongConverter) for models.Page.navigationId to 20000"), it looks like there's a type mismatch between the way a numeric value is being stored and retrieved. For example, in Java, it is not uncommon to store something as a Double and then mistakenly try to retrieve it as an Integer or a Long. So, can you verify that the declaration of navigationId in the dependent module is the same as the one you've shown here? They should share the definition, but its possible there's an alternate.

Another thing to check is that your code is putting a Long into your DBObject and not a float. For example, if you're inserting it via the shell, you'll need to use one of the wrappers, e.g.

db.Page.save({_id:NumberLong(20000)});

Otherwise, this will also cause a mismatch when you retrieve it; by default numbers in JavaScript are doubles.

查看更多
登录 后发表回答