how to set datasource properties dynamically - grails

I am using Grails and as my project's requirement I want to connect to databases as per users requirement. So I have to take the DB credentials like username,password,URL from user. How can I connect to their databases by setting these values in datasource at run time. Is there any way that I can set these values dynamically?

I will explain the concept and leave the implementation up to you. Be aware, this isn't exactly simple and does require you to do some research into the details, but if you are willing to do so, you can accomplish this.
The basic concept here is that each data source in your application is defined as a Spring bean. This is the default behavior of any Grails application. As such, you can replace a bean with a newly defined one. In your case you will want to do this with your second data source. The bean name is determined by how you have it named in your DataSources.groovy.
Take a look at the Spring section of the Grails documentation where it shows some examples of configuring a data source. The same concept will apply in your case. Just be sure you use the correct bean name and that you also call the destroy/close method of the existing bean before you replace it.
Depending on how you implement the replacement (and if you use a GenericBeanDefinition or not) you may want to use grailsApplication.mainContext.registerBeanDefinition(beanName, beanDefinition).
As I stated, this can be done, but you are going to have to learn a bit about the internals of Spring and bean definitions, as well as the API to build and manipulate them at run time.
Hope this helps get you started.

Related

How can I enforce using a GORM data service instead of GormEntityApi

How can I enforce that all entity persistence operations in my Grails application happen via GORM data services, and never directly on my domain classes (e.g. the methods in GormEntityApi and dynamic finders)?
Ideally the GormEntityApi and dynamic finder methods would not be available on my domain classes at all, but I'd also accept a solution that neuters the methods by causing them all to throw e.g. an UnsupportedOperationException.
I've done a bunch of internet searches, pored over the GORM documentation, and even dug around in the GORM code a bit, and I can't seem to find any information about this. Since data services provide all the same CRUD functionality as GormEntityApi and dynamic finders, this seems like a reasonable thing to want to do. I feel like I must be missing something.
How can I enforce that all entity persistence operations in my Grails
application happen via a GORM data services
There is no way to enforce that right now.
I've done a bunch of internet searches, pored over the GORM
documentation, and even dug around in the GORM code a bit, and I can't
seem to find any information about this.
We don't have support in the framework for doing that.
Since data services provide all the same CRUD functionality as
GormEntityApi and dynamic finders, this seems like a reasonable thing
to want to do. I feel like I must be missing something.
I don't think you are missing something. We have considered not adding the GormEntity trait to domain classes by default, but right now that happens and we don't provide a mechanism for turning that off.

How can I make a good use of the JSF 2.0 framework?

Currently I have only one controller AppController (SessionScope - ManagedBean) that handles all of the requests and logic of my system, but somehow this doesn't seem right. I want to make this project as modular as possible so it can be very easy to maintain.
I have read a little about Dependency Injection, but I just can't make it work, that is, I don't know what's the issue with the "scope" of the beans. For example, I have my AppController and my Users bean, but I can't make use of the AppController from the Users bean (although I have tried with dependency injection). I think that the logic of the users (edit names, set relationships, etc.) must be handled by the Users bean, but right now those tasks are handled by the AppController, which doesn't seem right.
The issue is, Is there any good tutorial where I can learn how to make a proper use of the JSF 2.0 framework? My objective is to make the AppController as light as possible. I have found several tutorials, but they seem to be more focused on older versions of the JSF or I just don't happen to understand them (maybe they are too technical, I don't know).
Any help with this would be very appreciated.
As to the concrete problem, you shouldn't have a single managed bean which acts as a front controller to handle all requests. JSF's own FacesServlet is supposed to do that. The common consensus is to have a single request/view scoped managed bean per <h:form> you have. And one or two session scoped bean(s) to represent the logged-in user and its settings like locale, if any. You could have an application scoped bean for applicationwide data such as dropdown constants.
As to the concrete question (which is rather subjective and per definition offtopic here, but ala), there is not really a simple tutorial for this. It's a matter of understanding what you're doing and what the code is doing and ultimately using the right tool for the job. In order to learn that, you've to read a self-respected JSF2 book from top to bottom and play a lot around with simple projects. JSF can't be learnt and fully understood in 1 day. It took me years. You can find useful links/references in our JSF wiki page.

Integrating ice/ace:dataTable with JPA and request-scoped beans

I'm wondering what is the right way to deal with dataTables that take input in a Hibernate/JPA world. As far as I can tell, one of the following three choices is causing the whole house of cards to fall apart, but I don't know which one is wrong.
Semi-automatic transaction and EntityManager handling via a custom JSF PhaseListener that begins and commits transactions around every request
Putting editing components inside a dataTable
Using request-scoped managed beans that fetch their data from a request-scoped EntityManager (with some help from PrettyFaces to set IDs on the request scoped beans from their URLs)
Backing a dataTable with a request-scoped bean instead of a view- or session-scoped bean.
I see an ICEfaces dataTable demo using JPA but they are both manually managing the transactions and not displaying editing components by default. You click on the row which causes an object to be nominated for editability and then when you hit "save" it manually reconnects the object to the new EntityManager before manually triggering a save. I see the click-to-edit function here as giving us a way to ensure that the right object gets reattached to the current session, and I don't know how one would live without something similar.
The impression I'm getting about the new ICEfaces 3.0 ace:dataTable (née PrimeFaces 2.0 dataTable) is that it is intended to be used in a View- or Session-scoped bean, but I don't see how one could get around StaleObjectState and/or LazyInitializationExceptions if one has model objects coming out of the DAO in request A and EntityManager A and then being modified or paged in by request B with EntityManager B.
I suppose it might work under Java EE through some kind of deep fu, but I don't have the luxury of upgrading us from Tomcat 6 to anything fancier right now (though it is my intent in the long run). We're also not about to start using Spring or Seam or whatever the other cool stuff is. ICEfaces is enough weird for us, probably too much weird honestly.
So to sum up, which of these is the wrong choice? The request-scoped entity manager, the request-scoped dataTable or using editing components inside a dataTable? Or is something else really at fault here?
If you'd ask me, the prime fault seems to be sticking to an almost bare Tomcat when your requirements seem to scream for something a little fancier. The mantra is normally that you use Tomcat when you don't need "all that that other stuff", so when you do need it, why keep using a bare Tomcat?
That said, the pattern really isn't that difficult.
Have a view scoped backing bean
Obtain the initial data in an #PostConstruct- (when there are no parameters like IDs) or PreRenderViewEvent method in combination with view parameters
Use a separate Service class that uses an entity manager to obtain and save the data
Make the entity manager "transaction scoped"
Without EJB/CDI/Spring:
Obtain a new entity manager from an entity manager factory for every operation.
Start a (resource local) transaction, do the operation, commit transaction, close entity manager.
Return the list of entities directly from your backing bean, bind the edit mode input fields of the table to the corresponding properties of the entity.
When updating a single row, pass the corresponding entity to the update method of your service. Apart from the overhead of getting an entity manager, starting the transaction etc, this basically only calls merge() on the entity manager.
Realize that outside the service you're working with detached entities all the time. There is thus no risk for any LazyInitializationExceptions. The backing beans need to be in view scope so the correct (detached!) entity is updated by JSF, which your own code then passes to the service, which merges it into the persistence context.
The flow for persisting is thus:
View state View scope Transaction scoped PC
Facelet/components Backing Bean Service
Strings ------> Detached entities --> Attached entities
(the flow for obtaining data is exactly the reverse)
Creating the Service this way is a little tedious and a kind of masochist exercise though. For an example app and just the two methods (get and update) discussed above it wouldn't be so bad, but for any sizable app this will quickly run out of hand.
If you are already adding JSF and JPA to Tomcat, just do yourself a favor and use something like TomEE. This is barely bigger than Tomcat (25MB vs 7MB) and contains all the stuff you're supposedly trying to avoid but in reality need anyway.
In case you absolutely can't upgrade your Tomcat installation (e.g. the product owner or manager thinks he owns the server instead of the developers), you might want to invest in learning about CDI. This can be easily added to your war (just one extra jar) and let's you abstract away lots of the tedious code. One thing that you also could really use is a JTA provider. This too can be added separately to your war, but the more of this stuff you add the better you'll be off by just using TomEE (or alternatives like GlassFish, Resin, JBoss, etc).
Also see this article, which covers various parts of your requirements: Communication in JSF 2.0

Do grails domain classes have to be tied to a database?

I am a complete noob when it comes to grails (and still very noobish when it comes to groovy) so I apologise if this is a dumb question.
I am building a simple web app and I want to control portions of the domain in my app based on file system objects (i.e. directory structure and file type) rather than database data. How easy is it to do this or are the domain objects so entwined with GORM that it is not worth the effort to try?
I ran into this question myself a couple of weeks ago.
You can just add the following snippet to the Domain Class.
def isAttached()
{
return false
}
Now it isn't connected to your database. Voila!
You can also use:
class YourDomainClass {
static mapWith = "none" // disable persistence for this domain class
See grails documentation and this answer. Appears to have been added in Grails 2.0.1 but not documented until version 2.3.0.
There is no built-in way to map domain classes to file system objects as you've described, but equally there is no requirement that your domain classes map to a relational database. The subject of how to create a Grails app that doesn't use a relational database is addressed
here and here (and possibly elsewhere).
A couple of ways to do this.
First, you can declare your properties that map to file system data as transient, and go to file system when getters / setters are called (you have to override them). You can also load them using onLoad if you need them to be in memory always.
Second - Hibernate handles the persistence. Hibernate allows for you to define your own user type, which can handle the persistence whichever way you want. This way it might happen for you more transparently (though you'd have to make sure you understand hibernate fairly well, to make sure there aren't any side effects, I am not sure).
http://i-proving.com/space/Technologies/Hibernate/User+Types+in+Hibernate

Grails build-test-data

Is it advisable to use the build-test-data plugin to load the bootstrap (seed/initial) data for an application. The plugin tutorial is excellent at http://bitbucket.org/tednaleid/grails-test-data/wiki/Home , but only mention about loading test data. There is a section about TestDataConfig , which allows to set default data. But is it a viable option if the data needs to persist in a larger scale, with complex relations.\
thanks.
Testing data is the primary focus of the plugin, but I use it for all kinds of data loading situations, including bootstrapping data into a new system.
The only thing you need to be aware of is that the plugin, by design, will fill in any holes in required data that you don't supply. This means that you should specify everything that you actually want specific values on (or putting it in the TestDataConfig that you mention). If you don't give build-test-data a value, it'll make something up and that might be something that you don't want.
The newly added functionality around buildLazy makes it even easier to hook into an existing graph of objects that you might have in a BootStrap configuration.
It depends on your data. If you only need a few things like administrator account info, list of categories, etc it should work fine. I'd use it if you’re testing your app with the initial seed data and everything works fine. For large or complex data imports I'd use a gant script to create and save for all the domain objects. For example I'm working on a project that requires me to move data out of a legacy database into a grails application. For this I run a script that uses JDBC calls to get all the old data out of the legacy database. I then create and save new domain objects based off this data. For an example of how to run a script that has access to the entire Grails context including Gorm see this

Resources