The use of join in Grails GORM queries - grails

In Grails we define domain classes in such a way that clearly indicates the relationship between domain classes such as one to many or belongsTo (if any). Since Grails is based on DRY, does that mean we do not need to use the join keyword when performing complex HQL queries in Grails DomainClass.ExecuteQuery method?

Grails doesn't change the way you write your HQL it is the same whether your using Grails domain classes or POJO's. If you need to write queries that navigate the object graph then you need to use the same syntax as you would with HQL like FROM parent p JOIN p.child c WHERE c.age = 10. Criteria queries work in the same way but you just get to use closures.
Take a look at the documentation (section 5.4.3) for more information.

In general no, you don't need explicit joins because Hibernate knows about the relationships of the tables based on the relationships of the domain classes. One exception is collections, and it is possible to use joins to customize the default behavior. The best resource on HQL is the Hibernate documentation itself: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html

Related

Indexing in many to many relationship grails

I have two domains Class A and Class B with many to many relationship. For performance tuning I want to add indexes in a_id,b_id columns of table a_b(table produced by grails). FYI I have added the indexes from query.
It looks like you'll need to create the index within the database itself. If there was an option to index the join table it'd likely be in the joinTable(), but it's not there.
I found this tutorial very helpful with many to many relationship in Grails.
Many-to-Many Mapping without Hibernate XML
This method will give you the separate index unlike joinTable().

Efficiency of querying a database with STI

I was curious how rails queries a table that uses STI. For example, if my parent class is Book and I have two subclasses ComicBook and Novel if I do something like
Novel.all.each
since there's only one table, does the server shift through all of the comic books as well? Is appropriate indexing automatically added to prevent this? Thanks
Well, you can't do Novel.each, each isn't defined on model classes. You can however do Novel.all.each ... where ... is some block.
As for how the query works, just call to_sql on any ARel expression. Novel.all will return the collection of models itself, so you need to go a step further to ensure a valid ARel expresion is returned by calling scoped.
[1] pry(main)> Novel.scoped.to_sql
=> "SELECT \"books\".* FROM \"books\" WHERE \"books\".\"type\" IN ('Novel')"
Indexing by most columns that are queried against frequently is a good thing to consider. Yes, without the index your rdbms will have to look at all records in the table as part of the above condition check.

How to require value for certain column in Grails/GORM mapping?

I have a grails application which works with a legacy database.
I have in almost all tables a column, let's say include. I want to include such entities in query results if and only if this column has a nonzero value.
Is there any way for specifying this on a per class / application criteria in grails, perhaps in a static mappings block? Currently I'm I specifying AND include == 1 whenever I make a database query.
I think this plugin will get you what you need.

How to map class hierarchy (base class and inherited classes) to a database

I want to create a hierarchical object model in ASP.NET MVC, but I'm not sure what would be the best way to design database for this. I have a Product base class with certain properties like Title, Price, OnHandQty etc. I have several inherited classes like Book, which has extra properties like ISBN number, Author etc. Many of my products will fall under generic (base) Product class, but some products will fall under these derived classes (e.g. Book). I am not sure what is the best methodology to map this to database. Should I create separate tables for each product type (including one for generic product)? Or is there any better way?
Please note that I'm not really asking about OR mapping. I know how to create classes from DB tables using Entity Framework. But in this case I am confused about the database design itself.
If you are going to use Entity Framework then you should check out Inheritance with EF Code First by mortezam. He explains three strategies that can be used for representing an inheritance hierarchy:
Table per Hierarchy (TPH): Enable
polymorphism by denormalizing the
SQL schema, and utilize a type
discriminator column that holds type
information.
Table per Type (TPT): Represent "is
a" (inheritance) relationships as
"has a" (foreign key) relationships.
Table per Concrete class (TPC):
Discard polymorphism and inheritance
relationships completely from the
SQL schema.
The idea (with Code First) is that you define your classes and inheritance and let the framework create the database for you. That way you don't need to worry so much about the database design.
You might also want to think about using an Object Database or one of the NoSQL storage strategies like Mongo DB which work better than relational databases when you have these kind of 'jagged' classes.

MongoDB, Grails, and relationships

I was curious about how the MongoDB plugin for Grails would handle relationships. In order to test this I made a very simple application with two domain classes:
Authors have two fields: String firstName and String lastName
Books have two fields: String title and Author author
After setting up MongoDB and Grails I made some Authors and Books and took a peek using the MongoDB interactive shell. What I found is that the relationships were being handled the same way they would be handled in a relational database: references to other objects' id fields.
So now for the questions:
In order for GORM to pull this off, does it need a separate connection to retrieve each document?
If yes, wouldn't this be better off in a relational database such as PostgreSQL or MySQL?
If the answer to the above two questions is indeed 'yes,' then is there a better way to manage relationships in a document database such as MongoDB? I realize MongoDB isn't supposed to be relational, but there are some things that I don't see how to get around relationships without duplicating data (thereby making update nightmares).
Edit: I also just noticed that grails is not sorting properly on the 'id' property of my authors. Does this have to do with using MongoDB? In the shell I can see that the _id property of all the documents made by Grails is of the datatype NumberLong.
I realize MongoDB isn't supposed to be relational, but there are some things that I don't see how to get around relationships without duplicating data
Then don't sweat it. MongoDB is not anti-relational, it's document-oriented.
In this case, Books and Authors are two top-level objects. It's not reasonable to nest either of them, they are both core entities in their own right.
In the case of each Book having only one Author (N:1), it's completely reasonable for the Book to contain a "Reference To" the Author. Sure you'll have to do two queries. But is that terribly different from doing a join query? The join query still has to do two index look-ups and two data lookups. So you're not really costing yourself anything here.
In the case of each Book supporting multiple Authors (M:N), then you have several options based on your needs.
I don't like to think of MongoDB as "not relational", I think it's cleaner to think of MongoDB as query-optimized.
I also just noticed that grails is not sorting properly on the 'id' property of my authors...
I would check directly with the Grails author. Sounds like they may be storing "strings" instead of actual ObjectIds (or MongoIDs). While not critical this may be a bug.
In regards to the id property, the documentation now shows that you can put a declaration of ObjectId id or String id in your domain class in order to not use the default GORM implementation of using an iterating long. Simply declare the field in your class, and the plugin will take care of the rest.

Resources