Which class/interface is the parent for all the grails domains.
I just want to know which class actually executes save method of a grails domain
Let us suppose we have grails domain with name book
Book book = new Book("1")
book.save()
There is no save method in book class so where does it actually resides.
https://gorm.grails.org/6.0.x/api/org/grails/datastore/gorm/GormEntity.html
GormEntity is the parent for all domains classes.
Related
In grails 4 (grails 3+), we have to mark the domain classes with multi tenant trait and also its respective services and controllers.
For eg :
class Book implements MultiTenant<Book> {
String title
}
#CurrentTenant
class BookService {
#WithoutTenant
int countBooks() {
Book.count()
}
}
Is there a configuration for gorm to make everything as multi tenant? My requirement is, based on domain name for eg: abc.com or xyz.com where tenants are abc and xyz i need to switch database but i don't want to go on to annotate each domain class and controllers.
Is there a configuration for gorm to make everything as multi tenant?
No.
You have options like you could build an AST transformation that would do such a thing, but no feature like that exists in the framework itself.
I want to bind view page params to non domain class(say *.java class).
Project projectInstance = new Project(params)
where Project is not Domain class, it is simply java class.
Does grails provide any plugin or any way to bind it to non domain class.
Thanks.
You cand try with bindData.
In controler:
Project project = new Project()
bindData(project, params)
I use inheritance in Domain Classes in my Grails app. Obviously, inheritance adds a "class" column to my database. The content of the "class" column is the fully qualified name of the Domain Class, e.g. com.myapp.MyClass.
Now if I ever so some refactoring and the class name is no longer com.myapp.MyClass but e.g. com.myapp.mypackage.MyClass, then the database still contains the old class name which now no longer exists in the app.
Is there any way to configure the string that is put in the "class" column? Like another unique identifier for the class which is then mapped to the class name in my Grails config or something like this?
I think what you need is discriminator for the class.
By default when mapping inheritance Grails uses a single-table model
where all classes share the same table. A discriminator column is used
to determine the type for each row, by default the full class name. ref
You can map it like this:
class PodCast extends Content {
…
static mapping = {
discriminator "audio"
}
}
Look this documentation it gives you more options to customize it in more details
http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html
Given these functional requirements:
User Management
Administrator
Librarian
Borrower
*The users have the option of logging-in via OpenID.
Property Management
Book
Memorandum
Circular
License
Normally, I would implement these in Java as:
interface User {}
class Librarian implements User {}
class Administrator implements User {}
class Borrower implements User {}
class OpenID {} //all Users HAS AN OpenID attribute (NULL if non-openId login)
interface Property{}
class Book implements Property{}
class Memorandum implements Property{}
class Circular implements Property{}
class License implements Property{}
But our project will use Groovy & Grails, which I haven't experience using yet. My question is,
how should the domain classes be designed based on the requirements above? I can't use an interface, and it seems inheritance is not a good practice. My idea is to use composition, though I'm quite bothered by the database tables that would be generated. What are the best practices in this situation?
Well first of all lets correct it, you can use inheritance in this case. You just need to change the convention of has a relationship to is a relationship.
Few factors to keep note of:
1. Grails works on convention over configuration.
2. You can use GORM which wraps the persistence layer and creates an Object Mapping for the underlying persistence layer with the help of Hibernate.
As per your functional requirement:-
If you do not want to have the User as part of persistence you can have an abstract class User which can hold the common properties of the User including the openId attribute. It has to be placed in src\groovy directory as per convention (since the base class is abstract, dependency injection will be defied)
The same goes for Property. Abstract Property class in src\groovy.
Now coming to the business models, extend each of the concrete entities (domain classes) from the abstract parent.
Summary:-
Create grails app
Under src\groovy(for example, I am considering a basic structure):
User.groovy:-
abstract class User{
String name
String emailId
OpenID openId
}
Property.groovy:-
abstract class Property{
String propertyName
}
Under grails-app/domain:
Librariran.groovy:-
class Librarian extends User{
//Attributes specific to Librariran
static constraints = {
}
static mapping = {
}
}
Book.groovy:-
class Book extends Property{
//Attributes specific to Book
static constraints = {
}
static mapping = {
}
}
So on and so forth. Groovy objects under grails-app/domain are considered concrete entities by Grails convention. More information you can obviously find here. You can also use composition if you come across scenarios, in fact I already mentioned that in User having OpenId.
Note:- This is context to latest version of Grails (> 2.x)
I have many domain classes in my application an for Audit logging I need the name attribute of each Domain class. unfortunately the name attribute is not generic in all Domains.
In my Audt log class I get the type of object modified/created/deleted and then save the id right now (which is common code since all domains have 'id' attribute) but now if I want to get the name attribute out of the domain from the ID, each domain has a different name attribute, like Resource Domain has resourceName, User domain has userName and so on... soI will have to handle each domain seperately (like have a map or bunch of switch statements for getting the name attribute from the Domain class name).
Is there a way I can have an alias mapping for each domain class's name field to be called 'name' . there should not be any change to the actual attributes in the Domains in whatever changes I do, I can add a column to Audit Domain but not other table changes.
Thanks in Advance
I don't think that there's any way to do this automatically.
As you guessed, you're going to either have to change all of the domain objects so that they have a 'name' attribute, or somehow maintain a map of which attribute in each class is to be considered the 'name'.
I suppose that one answer might be to add a getName() method to each of the domain classes, and return the appropriate value from that method.
If you really don't want to modify the domain objects at all, you can use groovy meta-object programming (MOP) to inject this method into each domain class from the BootStrap class.