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

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()

Related

Why must the _internal() be called in the class?

Even though I am familiar with singleton, Dart's factory is confusing. I have seen an existing question, but the only thing I got from the answer is that the name can be whatever identifier that starts with an _. Even though the person had asked why it should be called, the answer does not seem to be explaining that.
If I comment out the Dog._internal(); line, I get Method not found: 'Dog._internal'. It looks like calling a method, but is it like C's function prototype? But it has no return type. Can someone explain the Dog._internal(); line to me?
class Dog
{
static final Dog dog = Dog._internal();
//Dog._internal();
factory Dog()
{
return dog;
}
}
There are multiple concepts going on so lets go through the example:
factory Dog()
{
return dog;
}
This defines a factory constructor. Factory constructors are much like normal static methods but must always return an object which are compatible with the type of which the factory constructor is part of. In our example the factory constructor must return a Dog object.
It is not a constructor in that sense that we already have created a object when we enter this method. Again, it can be compared to static Dog Dog() but is allowed to override the default constructor. So we must create the object manually and return it.
This allows us to control the behavior of when objects are created and in our case allows us to have a singleton pattern so when somebody are trying to create an instance of Dog they will always get the same object.
Dog._internal();
This is called a named constructor. Constructors in Dart can have given names which makes it easier to distinguish different constructors. But also because Dart does not allows us to override methods with different number of parameters.
Also, because of the name starting with _ it means this constructor is marked private and cannot be used outside of the library it is part of. So if your code is part of a library, the code importing your library are not allowed to call your private constructor.
This is again a nifty trick to allow us to make a singleton since we don't want other than our own code to create a new instance (which are the only instance we want to create).
static final Dog dog = Dog._internal();
This is essential creating the singleton. The reason for this is that static variables in Dart are lazy-evaluated so the value dog does not really have any value before it is called. After first call, the value are "cached" so Dog._internal(7) are only called once as long our application (or more specific, our isoleate instance) are running.
I would properly call the variable _instance or _dog so it is also private.
Dog.foo(); defines a named constructor named foo that takes no arguments and has no body. It's equivalent to Dog.foo() {}. Similarly, Dog._internal(); defines a named constructor named _internal. This would be more obvious if the constructor took arguments and did work, for example:
class Dog {
static final Dog dog = Dog._internal(7);
Dog._internal(this.years) {
registerAnimal(this);
}
factory Dog() {
return dog;
}
int years;
}

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

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).

Grails Domain Class Abstract/Non-Abstract Dynamic Check

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

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