Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Querying embedded Fields giving ValidationException on disableValidation #961

Closed
mdoh opened this issue Jul 7, 2016 · 14 comments
Closed
Labels
Milestone

Comments

@mdoh
Copy link

mdoh commented Jul 7, 2016

Hi,

I get a ValidationException after updating to Morphia 1.2.0

The field 'data.data.id' could not be found in 'java.lang.Object' in Embedded Objects. at org.mongodb.morphia.query.QueryValidator.validateQuery(QueryValidator.java:99

Morphia Version 1.2.0
JDK 1.8
MongoDB 3.0.7

In MongoDB the corresponding Query
db.collection.find({"data.data.id" : "123"})
is working

Here is a Test:

import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.bson.types.ObjectId;
import org.junit.Before;
import org.junit.Test;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.dao.BasicDAO;
import org.mongodb.morphia.query.Query;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.BasicDBList;


public class ValidateEntityWithDBListIT extends AbstractMorphiaIT {

    private BasicDAO<TestEntity, ObjectId> dao;

    private ObjectMapper jsonMapper = new ObjectMapper();

    public static final String DATA = "[{ \"type\" : \"text\", \"data\" : { \"text\" : \"sometext\" } },  { \"data\" : { \"id\" : \"123\" }, \"type\" : \"image\"  }]";

    /**
     * 
     */
    @Before
    public void setUp() {
        this.dao = new BasicDAO<>(TestEntity.class, datastore);
    }

    /**
     * 
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testCreateEntityWithBasicDBList() throws Exception {

        TestEntity entity = new TestEntity();

        List<Map<String, Object>> data = this.jsonMapper.readValue(DATA, List.class);

        entity.setData(data);
        this.dao.save(entity);

        this.dao.get(entity.getId());

        Query<TestEntity> query = this.dao.createQuery();
        query.disableValidation();
        query.criteria("data.data.id").equal("123");

        TestEntity foundEntity = query.get();
        assertNotNull(foundEntity);
    }

    /**
     *
     */
    @Entity("CreateEntityWithDBListIT-TestEntity")
    public static class TestEntity {

        @Id
        private ObjectId id;

        public ObjectId getId() {
            return id;
        }

        private BasicDBList data;

        public BasicDBList getData() {
            return data;
        }

        public void setData(List<?> data) {
            Objects.requireNonNull(data, "data");
            this.data = new BasicDBList();
            this.data.addAll(data);
        }
    }

}
@evanchooly
Copy link
Member

Probably related #941

@mdoh
Copy link
Author

mdoh commented Jul 7, 2016

Yes, it seems so.

Is there a reason why the QueryValidator only breaks at Interface?

if (mf == null && mc.isInterface()) {
    break;
} else if (mf == null) {
    throw new ValidationException(format("The field '%s' could not be found in '%s'", prop, mc.getClazz().getName()));
}

@evanchooly evanchooly added the bug label Jul 7, 2016
@evanchooly evanchooly added this to the 1.3.0 milestone Jul 7, 2016
@evanchooly
Copy link
Member

That logic predates me so I can't say one way or the other why it breaks there though I have some guesses.

Can you share an example line or two of your json just so I can recreate this test locally. I have an idea of what it looks like but would like to minimize the assumptions I'm making.

@evanchooly
Copy link
Member

nevermind. just found that constant.

@mdoh
Copy link
Author

mdoh commented Jul 11, 2016

still broken in current 1.3.0-SNAPSHOT

@evanchooly
Copy link
Member

evanchooly commented Jul 11, 2016

That jenkins build is still running.

On Mon, Jul 11, 2016 at 10:38 AM, mdoh [email protected] wrote:

still broken in current 1.3.0-SNAPSHOT


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
#961 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAL5zWgNvStmDk1UDk0cbqRo5A-hLKzfks5qUlV8gaJpZM4JHNFQ
.

@mdoh
Copy link
Author

mdoh commented Jul 11, 2016

ok.

@evanchooly
Copy link
Member

It should be online now. At least, jenkins has pushed the bits.

--------------------------------

{ *name : *"Justin Lee", *
title : *"Software Engineer"
,
twitter : "@evanchooly http://twitter.com/evanchooly_"_,
web : [ "mongodb.com http://www.mongodb.com", "antwerkz.com"
],
location : "New York, NY" }

On Mon, Jul 11, 2016 at 10:46 AM, mdoh [email protected] wrote:

ok.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#961 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAL5zaJMmDMv2uTs0Sy6yCw602NeZsbCks5qUldHgaJpZM4JHNFQ
.

@mdoh
Copy link
Author

mdoh commented Jul 13, 2016

i tried morphia-1.3.0-20160711.144219-30 and it is still broken on my site:

The field 'data.data.id' could not be found in 'java.lang.Object'
at org.mongodb.morphia.query.QueryValidator.validateQuery(QueryValidator.java:97) ~[morphia-1.3.0-SNAPSHOT.jar:na]

@evanchooly
Copy link
Member

can you look at the test here and see how it differs from your situation?

@mdoh
Copy link
Author

mdoh commented Jul 13, 2016

I' ve seen your tests and I' m already trying running these on my machine

@mdoh
Copy link
Author

mdoh commented Jul 14, 2016

Your TestEntity has a different data object. As you can see on the sample above I am using a BasicDBList:

public void setData(List<?> data) {
    Objects.requireNonNull(data, "data");
    this.data = new BasicDBList();
    this.data.addAll(data);
} 

Because of that it can not map it in MappedClass

    public MappedField getMappedField(final String storedName) {
        for (final MappedField mf : persistenceFields) {
            for (final String n : mf.getLoadNames()) {
                if (storedName.equals(n)) {
                    return mf;
                }
            }
        }

        return null;
    }

If you change it in TestEmbeddedValidation it will fail aswell.

@evanchooly
Copy link
Member

I was guessing that'd be the difference. You really shouldn't be using BasicDBList directly. Can you change your model?

@mdoh
Copy link
Author

mdoh commented Jul 15, 2016

If I do so I get warnings: Parameterized types are treated as untyped Objects but it works now, thanks!
Why should I avoid using BasicDBList?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants