question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Migrating from createQuery() to find() doesn't work as expected

See original GitHub issue

Please ask your question and provide whatever background or supporting information you think might be relevant: Hi @evanchooly, I’m in the process of migrating from v1.6 to v2.0 and I’m having some trouble re-writing queries from createQuery() to find() because of some counter-intuitive behaviour

Code snippets

When using 1.6 the following simple mongo query would work:

               PricingVersion potential = datastore.createQuery(PricingVersion.class).order("-createdAt").get();
               // null check and logging
              return potential;

In 2.0 this becomes:

               return datastore.find(PricingVersion.class)
                               .iterator(new FindOptions()
                                               .sort(descending("createdAt")))
                               .next();

However the MongoCursor throws a NoSuchElementException.

Logs

After some digging in the logs I found that the mongo command has changed from (v1.6):

{"find": "PricingVersion", "sort": {"createdAt": -1}, "limit": 1, "$db": "datahub_v", ... }

to (v2.0):

{"find": "pricingVersion", "filter": {"_t": {"$in": ["PricingVersion"]}}, "sort": {"createdAt": -1}, "$db": "datahub_v", ...}

I would expect {"find": "PricingVersion"}

After reading through the source code I found I could workaround this issue by using find(final String collection, final Class<T> type) from here. My code became

               return datastore.find("PricingVersion", PricingVersion.class)
                               .iterator(new FindOptions()
                                               .sort(descending("createdAt")))
                               .next();

But this still throws a NoSuchElementException…

Here is the mongo request log:

{"find": "PricingVersion", "filter": {"_t": {"$in": ["PricingVersion"]}}, "sort": {"createdAt": -1}, "$db": "datahub_v", ...}

How can I properly retrieve the list of PricingVersions from mongo in morphia v2.0?

Additional info

In the migration to morphia v2.0, a field was removed in the PricingVersion class:

        # deprecated price curve
	@Reference
	@JsonAlias("curves")
	private Map<String, Curve> oldcurves = new HashMap<>();

On top of being deprecated, this field also caused problem in morphia 2.0 because the @ Reference annotation requires Map to have an id.

Is this related to the fact the query above is returning a NoSuchElementExceptionand not the list of pricing versions as expected?

Aside - refactoring

In https://github.com/MorphiaOrg/morphia/blob/master/morphia/src/main/java/dev/morphia/query/MorphiaQuery.java#L62 you might want to change the order of the parameters from

MorphiaQuery(final Datastore datastore, final String collectionName, final Class<T> clazz)

to

MorphiaQuery(final Datastore datastore, final Class<T> clazz, final String collectionName)

to match the overloaded constructor just below which looks like

MorphiaQuery(final Datastore datastore, final Class<T> clazz, final Document query)

It makes it slightly more readable and less confusing when reading this if statement

Thanks for reading this far! 😄

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
ppartarrcommented, Sep 17, 2020

I’ll stick to MapperOptions#legacy() for now then. I’ll keep an eye out on the docs and start planning the migration. Thanks for your help! 👍

1reaction
evanchoolycommented, Sep 16, 2020

What you’re running in to is, well, two things: a change in the default behavior and lack of sufficient documentation. How are you building your MapperOptions? Are you explicitly building a MapperOptions? In 1.6 dev.morphia.mapping.MapperOptions#builder() was deprecated in favor of dev.morphia.mapping.MapperOptions#legacy() because some defaults were going to change. If you don’t use MapperOptions directly, you’re getting the new defaults automatically.

One of those changes is the ability to set collection/field naming strategies. In the case of collections that is now camelCase which is what you’re seeing. If update your code to use dev.morphia.mapping.MapperOptions#legacy() when creating your Mapper, you’ll get the “correct” class name. You can also use dev.morphia.mapping.MapperOptions#builder() directly and just update the naming strategy to your personal preference.

This is a gap in the migration docs which I’ll update shortly to correct.

And yes, that constructor order is annoyingly inconsistent. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hibernate-Search wildcard search not returning expected results
1 Answer 1 ... Your queries don't include the string wildcard character ('*'). Maybe this will work as you want? ... if(Objects.nonNull(u.
Read more >
Migrating from Hibernate's to JPA's Criteria API
JPA's Criteria API is much more verbose. You first need to get the CriteriaBuilder and call the createQuery method on it to instantiate...
Read more >
Hibernate Search 6.0.10.Final: Migration Guide from 5.11
The idea is to use the migration helper temporarily to make most of the application code (search queries, …​) work, making it easier...
Read more >
Chapter 14. Creating and executing queries
TypedQuery instance. You create queries with the EntityManager#createQuery() method and its variants. You can write the query in the Java Persistence Query ...
Read more >
Issue with spring-data "startingWith" and hibernate 5.6.7 ...
Hello, I am trying to fetch some entity using a “find all by property starting with” query which amount to a CriteriaQuery using...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found