Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, May 14, 2010

Using more than one Datasource in a Grails project

Grails is designed to work with one DataSource and one SessionFactory which are the ones used by all domain classes to execute all the operations in the database, so there is no easy way to set up a second or more datasources to allow different domain objects to connect to different databases to read and store data.

One approach is to inject a second datasource and use it with Groovy Sql to retrieve data. For this what we do is create the datasource in the Spring resources file so we can get it later using dependency injection either in a Grails service, a controller or a domain class.

My example is simple, in my database I have a table user that is related to a person table, but the person table is not in my database is in another database and I need to read some person information like the name and email to display on my system, so I am going to create a service that is going to be the one in charge of connecting to this other database using the injected dataSource. This service is then going to be injected in my domain class to set up the data I need into specific transient properties.

So the first thing we need to do is to create my new dataSource in my Spring resources file, something like this:


import org.apache.commons.dbcp.BasicDataSource

// Place your Spring DSL code here
beans = {

dataSourcePostgresql(BasicDataSource) {
driverClassName = "org.postgresql.Driver"
url = "jdbc:postgresql://testserver:5432/test"
username = "username"
password = "password"
}
}


Then, I need to create a Grails service class to connect to the database and get me the data I need:


import groovy.sql.Sql

class MyPostgreSQLService {

def dataSourcePostgresql

boolean transactional = true

def getPersonData(long personId) {
if (dataSourcePostgresql) {
def sql = Sql.newInstance(dataSourcePostgresql)
def row = sql.firstRow("select fname, lname, email from person where id = ${personId}")
if (row) {
return [firstName: row.fname, lastName: row.lname, email: row.email]
}
}
return null
}
}


As you can see I am connecting to the PostgreSQL database using my new dataSource using Groovy Sql and executing a direct query to the "person" table.

Finally in my domain class I inject the service and populate the properties firstName, lastName and email with what the service is providing me. I am setting these properties transient because I don't really need to store them in my database, I just need to have them for display.


class User {

def myPostgreSQLService

String firstName
String lastName
String email
String userName
Date createdDate
Date lastUpdated

static transients = ["firstName", "lastName", "email"]

def String getFirstName() {
getPersonData()
return this.firstName
}

def void setFirstName(String name) {}

def String getLastName() {
getPersonData()
return this.lastName
}

def void setLastName(String name) {}

def String getEmail() {
getPersonData()
return this.email
}

def void setEmail(String email) {}

private def getPersonData() {
// Make the service call only if these values haven't been set yet
if (!firstName || !lastName || !email) {
def personData = myPostgreSQLService.getPersonData(id)
if (personData) {
this.firstName = personData.firstName
this.lastName = personData.lastName
this.email = personData.email
}
}
}
...
}


And that is it, next time you do user.firstName, the service will query the database and get the person first name for display and that operation would be totally transparent for the controller or whenever you are using this domain class.

The downside here is that we cannot integrate this DataSource with GORM and use all its advantages, so i would say that this is an easy way to retrieve read-only data, specially if the amount of data you are retrieving is not much, you could use it as well to insert data into this other database, however if you need to read and write data I would recommend you to take a look at the Grails DataSources plug in that allows you to use multiple data sources with GORM. You can check it out here

Tuesday, September 8, 2009

Grails - How to execute the parameters data binding process in an integration test

When executing a request in a web application in Grails there is a process that binds the request parameters with the controller "params" object. Grails have different listeners that are notified and then execute the binding.

The class UrlMappingsFilter, which is a Servlet filter that uses the Grails UrlMappings to match and forward requests to a relevant controller and action, is the one in charge of notifying these listeners so they execute the data binding. However, this step is not executed in an integration test by default, therefore if you need to test a controller action in an integration test, you need to notify these listeners manually so the binding is done and you can access the controller "params" object inside your test. The way to do this notification is by executing the following line of code:

controller.request.getAttribute("org.codehaus.groovy.grails.WEB_REQUEST").informParameterCreationListeners()

So for example if you were using a JSON content type the listener JSONParsingParameterCreationListener would be notified and then it would do the request parameters parsing allowing you to use the controller.params object on your test.

It is important to execute this code before actually calling the controller action method that you want to test so the "params" object is available when you need it. Also, to set the controller content-type to JSON doing something like:

controller.request.content-type = "text/json"

Where controller is the instance of your controller class.

Monday, April 14, 2008

Working with Enumerations in Java

An enumeration type is a Java type, which all values for the type are known when the type is defined. It is a special kind of class, with an instance that represents each value of the enumeration.

An instance of the enum class is called an enum constant, we will be referring to this term along the article.

There are some interesting things a developer must know when working with enums:

  • When declaring an enumeration, it is like declaring a class but with two exceptions:
    - The keyword enum is used instead of class,
    - Before declaring any class members, an enum must declare first all its enum constants.

  • All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance, an enum cannot extend anything else.

  • All enum are implicitly Serializable and Comparable.

  • Enums can have fields, methods and nested types, including nested enums.

  • Two static methods are automatically generated by the compiler:
    - values: returns an array of the enum constansts
    - valueOf(String name): returns the enum constant for a given name.

  • An enum type is not allowed to override the finalize method from Object.

  • Enum instances may never be finalized.

  • Nested enums can have any access modifier, while a top-level enum is public or package accessible.

  • Enums are implicitly static.

  • An enum cannot be declared abstract, but can declare abstract methods. Also, it cannot be declared final.

  • An enum constant declaration cannot have modifiers applied to it, except for annotations.

  • Restrictions of enum constructors:
    - All enum constructors are private.
    - An enum constructor cannot explicitly invoke a superclass constructor.
    - An enum constructor cannot use a non-constant static field of the enum.

  • Enum constants can have constant-specific behavior.

  • Some useful properties are set for enums:
    - The method clone is overriden to be declared final and to throw CloneNotSupported Exception.
    - The hasCode and equals method are overriden to be declared final.
    - The compareTo method is implemented and defined so that enum constants have a natural ordering based on their order of declaration (the first declared enum constant has the lowest position in the ordering).

  • The toString method returns the name of the enum constant.


When using an enum will depend on how sophisticated is the behavior of type, because if the behavior is too sophisticated, it is more likely the application might need to specialize that behavior. Enums are suggested for simple types like card suits or the days of the week.

Wednesday, October 24, 2007

A Java Certification or Not?

Lately I've been thinking about getting a Java Certification, but I've heard some opinions of people saying that a certification does not give an extra value to the person that has it, so I started thinking about it and it seems that some companies actually react when they see in your resume that you have certifications.

To get some more opinions, I posted a question in LinkedIn, I asked this:

For a Java programmer, do you think it really makes a difference to have a Java certification when looking for a new job?

I am interested in knowing if a certification is actually considered when evaluating candidates or if the employers only care about their own evaluations and candidate's past experience.

It was interesting because I got a lot of different opinions from people who are Java developers and from people who recruit.

Most of the answers agreed in one thing, a certification can't hurt no one, so in most of the cases companies would check your experience, your ability to solve problems and some other skills before actually caring about the certification. However, if they are interviewing two people and both of them have the same qualifications, but one has a certification they would probably hire the one with the certification because it is a plus, it means that this person studied Java to pass the test.

In my opinion, I don't think a certification would actually make a big different when your applying for a job if you don't have any experience. However, one of the biggest advantage of getting a certification is that you have to sit and study all the Java items required to pass this test and that gives you a big knowledge of the language because you are learning the theory and that is very important, since there are a lot of developers that can make things work but they don't know what is actually happening or how it is happening, they just know it works.

If you want to check all the answers go to my question in LinkedIn