hibernate « Intelligrape Groovy & Grails Blogs

Posts Tagged ‘ hibernate ’

Grails: Get table name mapped to a domain

Posted by roni on August 19th, 2011

Hi guys,

Recently while working on a project, I needed to get the table names associated with a particular domain as I needed to perform complex join operations on a particular table. The database that my team was working on was a legacy database. The domains that were created were mapped to particular tables to provide backward compatibility with the existing system’s database and, hence the table names were specified in the mapping closure. Now I needed a way to get the names of the tables that were associated with a particular domain.

The SessionFactoryProxy can be directly used to get the table name associated with the domain. So the code is as follows:

import org.hibernate.metadata.ClassMetadata
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder
import org.codehaus.groovy.grails.commons.ApplicationHolder

Class clazz = Class.forName("com.intelligrape.domain.Album", true, Thread.currentThread().getContextClassLoader())

String mappedTable 

def sessionFactory = ApplicationHolder.application.mainContext.getBean("sessionFactory")
ClassMetadata hibernateMetaClass = sessionFactory.getClassMetadata(clazz)
mappedTable = hibernateMetaClass.getTableName()

println "Mapped table name: " + mappedTable

Now the above modified code returns the table name associated with a domain.

Cheers
Ron
roni[at]intellligrape[dot]com

  • Share/Bookmark
Posted in Grails

A use case of Bitwise AND

Posted by Mohd Farid on April 15th, 2011

Recently, I used bitwise Anding in my grails project. I am sharing the approach that we followed by means of an example.


Suppose we have a domain class Person which can have multiple attributes like Smart, Intelligent, Talkative etc.

What sort of relationship comes to our mind when we see this?
I believe the obvious answer would be Person hasMany Attributes

Next, what if we want to optimize our design so that the searches on the Person becomes better.

Well, this was the question we were facing in our recent project where we finally used the bitwise AND.
We decided to have one field of type Long in our Person class. We named this as attributes . Soon, I ll be explaining why a long for Attribute…

We ensured that the Attributes are never going to be more than 20-30 . So, it became a nice candidate which could utilize the benefit of Bitwise ANDing.

We associated a binary weight to every instance of Attribute domain class.

The rows in the attribute table of our database looked somewhat like this

id | attribute      | weight
1 | Smart          | 1
2 | Talkative      | 2
3 | Intelligent     | 4
4 | Cooperative  | 8
5 | Ignorant       | 16

So, in order to save a Person who is Smart and Cooperative , we would set his attributes field.
weight of Smart + weight of Cooperative.
ie 1+8 = 9.

Suppose our Person table has some entries as follows:

id  | name  | attributes
1   | Tom   |  9
2   | Fred   |  12
3   | John   | 18

If we want to search a person who is Intelligent we need to have a final query like this

Select * from person where attributes&4 = 4
(4 is the weight of Attribute - Intelligent)

Search a person who is Cooperative and Talkative

Select * from person where attributes&2=2 and attributes&8=8
or more optimally,
Select * from person where attributes&10=10
(2 is the weight of Talkative and 8 is the weight of Cooperative)


Some points to be kept in mind before taking this approach:

There is a maximum limit of 64 values for the field on which we plan to do BitwiseANDing.
Bitwise AND is not directly supported by Hibernate, but we can add a custom function and dialect.



Hope this helped.

Thanks & Regards
Mohd Farid

  • Share/Bookmark
Posted in Database, Grails

Clearing Hibernate Query Cache in Grails

Posted by Vivek Krishna on June 23rd, 2010

In one of the projects, we had used Query Caching to improve the performance. However, it also meant that the updates/inserts into a table did not get reflected immediately, i.e. something like:

DomainClass.findByPropertyName("propertyName", [cache: true])

returned the same list as it was, before the insertion/updation took place. We found that this could be resolved by clearing the query cache every time an update took place. This was done in Grails by making a call:

sessionFactory.queryCache.clear()

Make sure that the artefact(controller, service, taglib, job etc.) has sessionFactory injected into it using the line:

def sessionFactory

Hope this helps.

– Vivek

vivek[at]IntelliGrape[dot]com

http://in.linkedin.com/in/svivekkrishna

  • Share/Bookmark
Posted in Database, Grails, Java tools

Grails criteria query example for unidirectional one-to-many relationships

Posted by Aman Aggarwal on June 14th, 2010

Following is an example of unidirectional one-to-many relationship:

class Employee {
    String name
    static hasMany = [roles: Role]
}
 
class Role {
    String name
}

How can we find all the employees with a particular role – “Grails Developer”?

Role role = Role.findByName("Grails Developer")

One way of doing this can be:

Employee.list().findAll{role in it.roles}

This is an inefficient way since, we are fetching all the records from the database every time. Also, in case we are showing paginated view of results, we will need to manage pagination ourself.

A better way of this will be using createCriteria() query:

List<Employee> employees = Employee.createCriteria().list{
    roles{
        eq('id', role.id)
    }	
    firstResult(20)
    maxResults(20)	
}

I am wondering what will be the query in case Role.groovy is an enum.


~Aman Aggarwal
aman@intelligrape.com

http://www.IntelliGrape.com/

  • Share/Bookmark
Posted in Database, Grails