grails populate controller model from bootstrap.groovy without database support - grails

I understand that the standard way to use bootstrap.groovy and a controller is to create the data and save them to DB in the bootstrap init()
The controller can then read the data, so the "middle man" between the two is the database.
But, what if I want to create data in bootstrap.groovy and not save them in the database (let's assume these data don't need to be saved), how can I inject the data into the controller so they could be used for views rendering ?
Let's take a simple example with a domain class Book. Simply in bootstrap I just want to crete a dummy list of 100 books:
class BootStrap {
def grailsApplication
def List<Book> books
def init = { servletContext ->
books = new ArrayList<>()
for (int i=0; i<100; i++) {
books.add(new Book(numPages: 20))
}
}
def destroy = {
}
}
The goal is now to expose/inject he list of books to a BookController.
How would I do that? I could not find a simple way or an answer anywhere about this

Services are singleton in Grails by default, so you could store that data in a service. But you have to be careful, because a service could be used concurrently.
https://docs.grails.org/latest/guide/services.html

To generalize the problem I have posted above (after reading the answer from quindimildev) generally every framework should have a way to perform initialization operations ... such as initializing a cache from a file or database or 3rd party services. By the time the application has started those data are in memory ready to be used by controllers, etc...
The typical applications/examples I have seen for grails don't take this into consideration, and they assume your database is populated and read through controllers actions. This is fine for most applications, but I would be surprise if grails doesn't provide a mechanism to build a cache at start up (one time operation that could take a few seconds) that can be available to all controllers once the application has started.
I hope this clarifies the scenario I am trying to address

Related

Grails and datasource usage

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.

complex hierarchy updates based on form input

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.

Grails and hsqldb

I was wondering how to persist data to a hsqldb. For example I am trying to save a simple name to a database but I cant seem to figure out how to persist it.
The recommended approach is to create a domain class with a String name property. Then you can save it, and you're done. First, create the domain class:
$ grails create-domain-class com.foo.Person
Then edit the grails-app/domain/com/foo/Person.groovy:
package com.foo
class Person {
String name
}
In controller actions or service methods you can create, save, and retrieve data:
def heMan = new Person(name: 'He Man')
if ( !heMan.save() ) {
// Handle problems saving (e.g. constraint violations)
}
def h = Person.findByName('He Man')
println h.name
An alternative approach is to work with JDBC directly. You can have dataSource bean automatically injected into your controller, then use the groovy.sql.Sql class to query that dataSource. Check out this stackoverflow.com question.
Two ways:
GORM
raw JDBC (via spring's JdbcTemplate)
I would suggest starting with a good Grails tutorial such as this one at IBM or one of these. Learn to use GORM. It will make your life better.

Is it possible to set a scope to a domain class?

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.

Queries count for page in asp.net mvc

I want to calculate how much queries are executed when i request a page in asp.net mvc. Difficults in page logic: sum queries are executed in main controller action, but others - in widget controller actions, which are called by Html.ActionLink in master page.
I wrote base class for all controllers in which i'm encapsulate query called function to increase queries counter - static variable. On page loading it work nice, all queries are counted, but when i requested second page my static counter doesn't reset, what should i do?
If possible avoid using a static variable. An instance variable on the base controller would work just as easily if all the methods shared the same controller instance. I assume that you're not instantiating new controllers to execute the other actions.
EDIT: After thinking about it, a simple static variable won't work as it will be shared across all requests. You'll need to use some sort of dictionary keyed by some unique id identifying the request. Perhaps based on a combination of the HostAddress and a timestamp created when the request is initiated. Perhaps using the application cache would work so it's available from everywhere and automatically cleaned up when you are done. This is only going to get more complicated as you consider all the possible way that multiple threads may interact. Again, I'd say trying to use an instance variable may be the best way to handle this.
extend your MvcApplication Class (in your global.asax) with
public static int QueryCount { get; set; }
then create a handler for the MvcApplication.BeginRequest event or extend your existing handler with
this.QueryCount = 0;
and in your BaseController Class you can increment your counter with
MvcApplication.QueryCount++;
hth
Are you using SQL Server? If so you can use the SQL Server Profiler from the Tools menu to see how many queries are run for a specific page.

Resources