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

Query Item.where('name = "x"') returns collection of GroovyRowResult #16

Open
aadamovich opened this issue Dec 9, 2014 · 7 comments
Open

Comments

@aadamovich
Copy link

I would expect the where method to return a collection of the Item class, but it returns a collection of GroovyRowResult, which kind of cancels the purpose of ORM

@kdabir
Copy link
Owner

kdabir commented Dec 10, 2014

I wanted to coerce the result to a object of class but all properties were accessible with a dot on the result anyways so thought it would be overkill to iterate (collect) over whole list to create objects.

A point in favour of coercing is that it makes methods of object available on the result objects. I am keeping the issue open. I think at some point coercing will have to be implemented.

@aadamovich
Copy link
Author

Also, the properties returned in GroovyRowResult object are all in upper-case. That means I have to write different code for adding the object and reading the object.

@kdabir
Copy link
Owner

kdabir commented Dec 10, 2014

Not really, if you check this assertion, it would still work with lower case, upper case or mixed case. Ideally, it should not work this way and should be case sensitive as would a normal property. But we certainly don't need to write property name in different case than our class.

Just for example, I have modified the test and it still passes for me:

    void "test where selects from table with where clause"() {
        new Person(name: 'Batman', age: 35).save()
        new Person(name: 'Spiderman', age: 30).save()

        assert Person.where("age > 30").collect { it.Name } == ["Batman"]
        assert Person.where("age > 30").collect { it.name } == ["Batman"]
        assert Person.where("age > 30").collect { it.NAME } == ["Batman"]
    }

@aadamovich
Copy link
Author

Yes, you are right. GroovyRowResult property retrieval is case-insensitive. Though, it still does not help much for type mapping :). I tried something like new Person(record), where record is GroovyRowResult, which, in fact, implements a Map and should potentially work with map-based constructor of the Person class. But it does not work, because it gets to know only the upper-case property names and fails.

@kdabir
Copy link
Owner

kdabir commented Dec 16, 2014

Valid point. Here is the code that could be used as workaround for now, until I make changes to where to return a Collection of ModelClass rather than GroovyRowResult.

Person.where("age > 30").collect {
    new Person(it.subMap(new ClassMetaData(Person).fieldNames))
}

It's kinda ugly but should work just as a fallback until it's implemented within gstorm.

I am still weighing the cost v/s benefit of explicitly creating objects of ModelClass type vs return the GroovyRowResult. What do you think?

@aadamovich
Copy link
Author

My first impression from the examples in the README was that I will get a model class, but not GroovyRowResult. So, I think at least it should be mentioned in README somehow, or the API should give a clear distinction.

I'm using GStorm to implement a simple mapping for a simple JSON API and the same model class is used both for JSON and SQL model mapping, which is fine for the simple use case that I have. The only problem was that I had to handle the mapping from GroovyRowResult back to Model class in order to be able to render JSON out of that class using Jackson.

If where returns a collection of model classes, then the model class can be used in any other mappings that that class may have e.g. JSON, XML, CSV etc.

@kdabir
Copy link
Owner

kdabir commented Dec 17, 2014

Yeah, that's confusing if it's not documented.

I am just thinking out loud here, I am considering the mapping back to the Model class as it's a better approach despite having a small overhead in terms of processing. OR provide a helper to where so that row can be easily converted to model object.

Just thinking of cases when the reverse mapping breaks for some reason, like type mismatching for dates etc. String, numbers etc can be be easily used in map based constructors using submap of GroovyRowResult. Complex datatypes in model class would need reverse mappings. I might be wrong here and it would work out of box. I will need to test it to confirm.

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

No branches or pull requests

2 participants