Friends:
In the service class I am trying to query the DB and get result to populate my domain class. I am not sure if I thinking this correctly or I have to use the find methods approach to fill my domain classes ?
The understanding I have is:
Grails thru URLMappings will call my controller and inside that I can do a direct instantiation of Service class.
I am then using SQL directly there inside Service class to iterate thru the Resultset and populate the Domain class list and return that to controller class which will then return a list back to the REST call user.
Is this the right approach or I have to call Service from controller but using the find method and that will fill the list and that should be used to return the list ?
In all cases I am using the H2 db itself.
Regards and Thank you for your time.
-Narahari
As per the standards, Flow goes from controller > Service > DAO.
All the business logic should be written in the service class only.
As you are using DAO layer is hidden through GORM.
Grails is very powerful and productive language. You use GORM for database activity. For your scenario, you could use findAll, createCriteria, HQL or native SQL query approach, but the flow should not be broken. It means that if write database related code in the controller then in future it will be difficult to maintain debug code.
Related
I am trying to understand the best way to work with complex hierarchies of objects that i manipulate based on data on forms in Grails.
I cannot use the command object as my form is dynamic (users can add any number of records). I am told we should parse the params in controller and let services do the transaction activities on the domain objects and thus reduce coupling. Sometimes this doesn't seem straightforward.
I have a few lists of child domain objects in a base domain object that is being 'updated' which means the list could have grown or reduced, meaning some domain tuples will need to be added/removed, how do i pass that information from controller to service without making a function with 8 parameters? If anyone has any strategies you've used, please share. I am sure this is not uncommon but I haven't seen any discussions on such a question.
e.g.
class DomainA {
List<DomainB> bList
List<DomainC> cList
DomainD domD
}
class DomainD {
List<DomainE> elist
}
How about relying on ajax. You might save classD and then class A, or use a command object to save both. Then with the Id´s of these two classes you might add everything else you need using ajax.
I have a n-tier solution with these projects in it (simplified for this question):
Domain
Logic
Web
In the "Domain" project I have a "Repositories" namespace and each repository is mapped to a different table in the DB and query its data.
For example - the tables Customers and Orders will have the corresponding repositories - CustomersRepository and OrdersRepository.
In the Logic project I instantiate these repository objects and call their methods which actually query the DB.
Lets say I want to show a report that display some data from both tables.
This report is constructed by a collection of custom objects - IList<ReportObject>.
Now, this ReportObject object has no corresponding table in the DB and therefore has no repository object.
My question: Where should I put the part of code that actually query the DB and fetch IList<ReportObject>? Should it just be in some data controller in the Logic layer? or create another repository for the reports? Any other option?
While I think this is mainly a question of opinion, here goes:
You can create a QueryStore<ReportObject> instead of a Repository<ReportObject>. The name QueryStore is just something I came up with, it's not a coined term.
The function of such a query store would be to, well, run queries on data that is not covered by any repository. It would contain only queries and so can, for instance, easily be implemented using LINQ on top of Entity Framework querying database VIEWs for instance.
I'd put it in a custom repository (as this is not a CRUD operation). You can extend Repository (if you're working with a generic repository) and create one for the query. I wouldn't put queries in other place rather than Repositories since you'll brake the encapsulation of what Repository does. Imagine you change the database in the future, it won't be enough to change the repositories layer. Another reason to not put it there is that the logic will be spread around the application instead of being everything in just one place which simplifies debugging and improvements in the queries.
Hope it helps. Guillermo.
The repository pattern is used to encapsulate CRUD operations, but in your case you do not need any Insert or Update. I would put this into the Logic layer and access the DB directly from there.
What are the pros and cons of writing class methods in grails domain classes? I am asking, because I often do not see any grails projects with methods inside the domain classes, only data members. Is there a disadvantage to doing so?
When a domain class (not just in grails, but in object oriented programming in general), this is known as an anemic domain model. Martin Fowler proposes that domain logic gets put into the domain class to create a rich domain model. By doing this, domain classes become smarter and know how to perform operations, rather than having another service class that has to operate on the domain class. The pros of having a rich domain model is that the class encapsulates more of its own behavior, and it is more self contained. On the flip side, it does make the domain class more complex. Though I think the domain class should be more than just a business object.
In grails, I tend to try to use a combination of a rich domain model and using services. It's difficult to make a blanket statement as to when a method should be in a domain class and when it should be in a service. As a general rule though, if an operation is complex and requires multiple collaborators, I'll tend to put it in a service class. If the method seems like it should be behavior on the domain class, I'll put it there.
To give a more concrete example, let's take a Person class.
class Person {
String firstName
String lastName
List<Person> friends
}
In our application a person can speak. Now I can have a TalkService that knows how a person talks. But in this case, I think that talk is a core behavior of the person, so I would add a talk method to Person.
Let's say I also have functionality where I want to find all of the friends of friends of people (2nd degree friends). To me, this is not core behavior of a Person, so I woul delegate this out to a service.
To recap, in general I would add methods to the domain class when it is core behavior of the object (e.g. is it a domain method), otherwise, I would put it in a service.
In a Java project, you must have POJO classes that represents the model.
For example: Person, Invoice, Book, ...
Then there is the service layer, which contains interfaces for users to do some database queries, it takes in parameters your Model, and also return Model, and there is the controller layer which is responsible for redirection and inject your services.
In grails, this is very easy using injection of services into your controller
Now, when do we need to use methods inside the domain classes ? it's when only the model which responsible for what do we need to do, for example, how old is a Person X (it's from the date of birth), how many items exist in a Invoice (from the List), the think is we use that only when we manipulate the data of the current object.
For save method for example, you cannot add it in your model
PersonController :
def personService
def save() {
...
Person person = ...
personService.save(person);
...
}
This is more evolutive
I'd like to know if it's possible with grails to specify a scope for the domain classes.
Few words to explain how my application is working at the moment:
- database access is done through an external "module" using SQLJ. This module is user by controllers in my grails app.
- a user ask for specific information submitting forms -> request submitted to the external module -> information extracted from the database -> information loaded into grails mem DB (HSQL) -> information displayed in views.
It works fine in development environment as i'm the only one using the application. But i'm wondering how the application would behave with two or more users. I mean, do the information loaded into grails memory database will be shared between users or not? And how not to shared information requested by one user with the others?
Thanks in advance for any help about this subject.
Regards.
All data in the database is shared across all users of the grails application. You would have to write a custom query to limit the data returned to a specific user. Based on your application maybe something similar to the following.
class DomainClass1 {
//fields you get from SQLJ go here
int userId
}
To get data into an instance of your domain class.
def domInstance=new DomainClass1()
domInstance.loadFromSQLJ() //call the SQLJ module and put it's data in the domain class
domInstance.userId=5 //assign the user associated with this info
domInstance.save()
Then when you want to display info for the user with the userId 5
def domInstance2=DomainClass1.findByUserId(5)
//Do stuff with domInstance2
It will be shared between all users.
But it depends on you, as for any other database, there must be some criteria (db column) by which you can choose only information related to current user.
In our project, we overrode domain classes' get(), list() that take into account domain aggregate root (a User or whatever), and also check all the named queries.
This leaves off all the other means of accessing instances, like findBy*(), criteria, findWhere() (though you can also override the dynamic methods), or HQL, but anyway reduces the amount of security review by 80%.
Suddenly it turned out to be OK to use DomainClass.list() in scaffolding.
in our new software project, we have the following requirement: A webpage shall show a set of data. This data shall be editable by some users (assigned to roles, i.e. manager), and only viewable by others. The tricky part is described by an example:
A User-page consists of address data and account information. The addess data shall be editable by the user and the manager and viewable by all users, while account information shall only be viewable by the actual user and the manager.
I have read a lot of information about SpringSecurity. It provides a very good framework to gran permissions on urls and methods and even domain classes. But what I need is field level ACLs. At least, that's what I think at the moment.
So, the question is: How to solve this problem using Grails?
Thanks a lot in advance,
Regards Daniel
Spring Security (Acegi Plugin) is definitely the way to go with Grails.
There is a taglib you can use that will allow a page to be different for different roles such as the following:
<g:ifUserHasRole roles="ROLE_ADMIN">
html code for extra fields
</g:ifUserHasRole>
Me, I'd encode it on the domain class, emulating the way GORM has you annotate the domain classes (static access = [field1: "ROLE_USER", field2: "ROLE_ADMIN,ROLE_USER"] as an example). Then build a method your controller could use to redact them for a given user. That method could use the domain class's annotations to decide how to redact it. Then, metaprogram it onto each of the domain classes the way plugins do.
Similarly, write the opposite method to restrict data bindings of params into the domain class, write your own data binding utility method, then metaprogram it onto each domain class as well.
Then you can just use instance.redact(user) or instance.bindData(params, user) to do what you want, and it's practically declarative syntax.
We have a similar situation and use both the ifUserHasRole tag in the gsp to drive the appropriate presentation and the we have a filter that enforces the rules based on the action being called. For example, on user controller we would only allow the management roles to call save action, or if the user.id is the same as the session.user.id. This seemed to be the best option for our situation.
What about creating an ACL class like this:
class ACL(val entry: Entry*) {
def isAccessAllowed(subject: String, permission: String): Boolean = ...
}
class Entry(val subject: String, val permission: String*)
usage:
new ACL(
new Entry("dave", "read", "write"),
new Entry("linda", "read")
)
(This example is in Scala, because I found it more expressive in this case, but it should be easy to transfer it to Groovy.)
You would then connect an ACL object with the object to be protected.