Grails Domain Class Abstract/Non-Abstract Dynamic Check - grails

I have a loop in my controller that does something like this:
for(d in grailsApplication.domainClasses) {
def c = d.getClazz().count()
// construct table containing object instance counts
}
My intent is to use this loop to count the instances of non-leaf domain classes in my database. Is there a way to query the domain class itself to find out if it is abstract or not? I wasn't sure if there were some member functions automatically added by the framework since I am still new to Groovy/Grails. I couldn't find anything that addressed it in the Grails documentation.

Figured it out after a few minutes of poking around the Groovy documentation. The function isAbstract() can be invoked on the domain class to determine whether or not the domain class is a leaf node in the class hierarchy

Related

In Grails, how can I get a reference to the datasource used by a particular class?

In the project I'm working on (in Grails 2.5.4/Hibernate 4.3) I have a bunch of different classes, using a few different dataSources. I need to determine whether two given Class objects use the same dataSource. What I would like to do is something like:
Boolean doDataSourcesMatch(Class a, Class b)
{
return a.mapping.datasource == b.mapping.datasource
}
But of course that doesn't work since a.mapping is a closure. Does anyone know how to access the dataSource used by a class? I don't need to know any of the properties of the connection, just whether queries on the two classes will use the same connection.
Many thanks!
Although none of these spell anything concrete out, they may help:
http://grails.1312388.n4.nabble.com/How-can-I-get-the-column-name-that-a-property-maps-to-for-a-domain-class-td4633766.html
How to get the name of the table GORM object is mapped to?
I haven't found anything specific, but this is all rather strange. I mean you already know and I presume this is some dynamic query otherwise you coding it would know what to query together etc.
Anyhow as a workaround, unsure if it can be since it depends on how many domainClasses we are talking about, and if this is something you have already put in place or thinking of writing up i.e nothing written in either case if you could add your own getter to all the domain classes in question
//
static String getDataSrc() {
return 'data_source_a'
}
//or
static boolean canQuery() {
return true/false
}
You could just check from anywhere something like this:
boolean canQuery = UserAttributes.canQuery()
String currentDataSource = UserAttributes.dataSrc
Since they are static methods, no instantiation is required. This means if you have
userObject(1) you don't need to do:
User user = User.get(1)
if (user.canQuery()) {
// this is ok
}
You can just call out the method directly from anywhere By referencing the upperCase class name and its method.
String currentDataSource = UserAttributes.dataSrc
//Where this is exactly the same as above
String currentDataSource = UserAttributes.getDataSrc()
E2A: The answer is:
import org.grails.orm.hibernate.cfg.GrailsDomainBinder
class TestController {
//either this method
def binder = new org.grails.orm.hibernate.cfg.GrailsDomainBinder().getMapping(Photos.class)
println "binder : ${binder.table.name}"
println "b: ${binder.datasources}"
//Or this
def dc=GrailsDomainBinder.getMapping(Photos.class)
println "-dc is ${dc}"
println "${dc.datasources}"
}
dc.datasources
is a list so you need to compare lists.
Of course silly me, if you are querying something like in HQL where you are giving dynamic table names ${tableA} ${tableB}
You will need to access actual domain class to be able to call GrailsDomainBinder
So something like: def domainClass = grailsApplication.getDomainClass(domain).clazz
would give you your actual domainClass for a given tableName. But your domain would have to be a fully qualified packaged name so that will cause you issues again.
If you querying com.domain.users.tableA and com.domain.info.tableB
So You could instead use If outside of service/controller):
def domainClass=Holders.grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz
or without Holders if you are declaring grailsApplication in controller service:
def domainClass=grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz

Check for annotation present on superclass field

I have problems to check if a persistent property in grails has an specific annotation for fields that belong to superclass ... ane then get it's name and value.
I am getting the persistence properties as:
GrailsDomainClassProperty[] persistentProperties = new DefaultGrailsDomainClass(entityClass).getPersistentProperties();
That works great ... but later i found that getDeclaredFields only retrieves the actual class fields (not superclass) and things starts to look not very Groovy.
Is there a prefered Groovy way to do this?
No, you should use this code for all super classes. The same will be for children classes.

Grails: #BindUsing on a class being ignored and #BindUsing vs ValueConverter

I need to do some custom data binding and I tried to use the #BindUsing annotation on a class (http://grails.org/doc/latest/api/org/grails/databinding/BindUsing.html), however, it's being ignored. I am under the assumption that since the annotation is used on the class that would mean that every time a data binding happens and that class is involved, the BindingHelper class would be used, but it's never actually called. Is there something that I'm missing or doing wrong?
Here's the class definition where UserBinding is a class that implements the BindingHelper interface:
#BindUsing(UserBinding)
class User extends SomeOtherClass
{
...
Also am I correct in understanding that basically creating a ValueConverter and using #BindUsing on a class accomplish the same thing?
BindUsing on a class is not used often and there seems to be a bug reported around that already. [From the link] The problem could be that there are multiple request parameters with the same name it might be using the helper only for the first one.
Using a property level #BindUsing annotation should be simpler to implement and is less likely to fail (even when there are multiple entries in the params map with the same name).

Getting Item_$$_javassist_165 from ins.getClass().getSimpleName()

I've three classes that implement the composite patter, Item, Cluster and Element.
class Item extends Locatable {
...
}
class Cluster extends Item {
static hasMany = [items:Item]
...
}
class Element extends Item {
...
}
My domain model is more complex than this, but it's just an example.
When I have an instance of Item and I want to know if it is a Cluster or a Element with ins.getClass().getSimpleName() I'm getting a weird class name: Item_$$_javassist_165, if I do a println ins.toString() I get the correct class name printed (the toString method returns this.getClass().getSimpleName()).
how to get the correct class name? What is this "Item_$$_javassist_165" class name?
What is this "Item_$$_javassist_165" class name?
It means that the object you have is a Hibernate lazy-loading proxy. The first time you try and access anything other than the id of that object, Hibernate will go to the database and load the real data, then delegate any future method calls to the real object.
The obvious approach of ins instanceof Cluster may not work correctly in the presence of proxies when you have one domain class that extends another, but GORM provides an injected instanceOf method that does what you need and will handle proxies correctly.
if(ins.instanceOf(Cluster)) { .... }
You can use GrailsHibernateUtil.unwrapIfProxy(object) to receive the original object instance from a proxy object. After unwrapping you should be able to get the real class name with getClass().getSimpleName(). Be aware that you loose features like lazy loading on the unwrapped object.
I find a method that give the real name:
org.hibernate.Hibernate.getClass(ins).getSimpleName()

GORM list() to return superclass objects only

I have a simple object hierarchy, and I want to query each of the objects using list(). The problem is that because of polymorphism, Task.list() returns both instances of type Task and ComplexTask.
class Task {
}
class ComplexTask extends Task {
}
I realize I can solve my problem by having a common abstract superclass, or filter results based on returned type, but was wondering if there is a way to use dynamic finders and get back superclass instances only.
Using the default table-per-hierarchy inheritance strategy, you can do something like this:
Task.findAll("from Task as t where t.class = 'Task'")
i think that has to do with lazy loading, because the real instance is not loaded completely not only for relations but also for inheritance.

Resources