Thursday, April 15, 2010

Deploying war to Tomcat using Maven

Step1: Add following in tag:


Step2: Add the username and password for the manager account in $MAVEN_HOME/conf/settings.xml file.
value in tag in step1 should be same as id in in step2


Step3: Maven command to build & deploy
        mvn clean install tomcat:deploy


to undeploy use: 
     mvn tomcat:undeploy


This does:

  • Deletes the service-war/target output folder if it already exists (same as mvn clean alone)
  • Recreates the folder and generates and compiles the Java classes into it (mvn package)
  • Creates a WAR file for the web service provider and JAR file for the JAX-WS artifacts (mvn package)
  • Installs the JAR and WAR into your local Maven repository (mvn install)
  • Undeploys the previous WAR file (tomcat:undeploy of the Maven Tomcat plugin) from Tomcat
  • Deploys the new WAR file onto Tomcat. (mvn tomcat:deploy)

Wednesday, April 14, 2010

Metro over JAX-WS

Metro has two fundamental levels:
- JAX-WS RI (that follows the JAX-WS JCP specification) - this includes JAXB
- WSIT/Tango - this provides WS-*: Security, SecureConversation, Trust, ReliableMessaging, AtomicTransactions, MEX

Unless you need the upper level WSIT features you can just use JAX-WS. JAX-WS supports SSL (it supports WS-I BSP).

If you want end-to-end message-level security then you need the WSIT/Tango layer of Metro. WSIT is intended to provide compatibility across the webservices developed in Java & .Net3.0 platforms, along with security, reliable & transaction guaranteeing features.

Hibernate Object States

Hibernate object states

* Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition).

* Persistent - a persistent instance has a representation in the database and an identifier value. It might just have been saved or loaded, however, it is by definition in the scope of a Session. Hibernate will detect any changes made to an object in persistent state and synchronize the state with the database when the unit of work completes. Developers do not execute manual UPDATE statements, or DELETE statements when an object should be made transient.

* Detached - a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again. This feature enables a programming model for long running units of work that require user think-time. We call them application transactions, i.e., a unit of work from the point of view of the user.

Detached Objects & re-attaching them:

Many applications need to retrieve an object in one transaction, send it to the UI layer for manipulation, then save the changes in a new transaction. Applications that use this kind of approach in a high-concurrency environment usually use versioned data to ensure isolation for the "long" unit of work.

Hibernate supports this model by providing for reattachment of detached instances using the Session.update() or Session.merge() methods:
// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catId);
Cat potentialMate = new Cat();
firstSession.save(potentialMate);

// in a higher layer of the application
cat.setMate(potentialMate);

// later, in a new session
secondSession.update(cat); // update cat
secondSession.update(mate); // update mate

If the Cat with identifier catId had already been loaded by secondSession when the application tried to reattach it, an exception would have been thrown.

Use update() if you are certain that the session does not contain an already persistent instance with the same identifier. Use merge() if you want to merge your modifications at any time without consideration of the state of the session. In other words, update() is usually the first method you would call in a fresh session, ensuring that the reattachment of your detached instances is the first operation that is executed.

The application should individually update() detached instances that are reachable from the given detached instance only if it wants their state to be updated. This can be automated using transitive persistence. See Section 10.11, “Transitive persistence” for more information.

The lock() method also allows an application to reassociate an object with a new session. However, the detached instance has to be unmodified.

//just reassociate:
sess.lock(fritz, LockMode.NONE);
//do a version check, then reassociate:
sess.lock(izi, LockMode.READ);
//do a version check, using SELECT ... FOR UPDATE, then reassociate:
sess.lock(pk, LockMode.UPGRADE);

Note that lock() can be used with various LockModes. See the API documentation and the chapter on transaction handling for more information. Reattachment is not the only usecase for lock().

saveOrUpdate() method

ither saves a transient instance by generating a new identifier or updates/reattaches the detached instances associated with its current identifier.

// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catID);

// in a higher tier of the application
Cat mate = new Cat();
cat.setMate(mate);

// later, in a new session
secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)

The usage and semantics of saveOrUpdate() seems to be confusing for new users. Firstly, so long as you are not trying to use instances from one session in another new session, you should not need to use update(), saveOrUpdate(), or merge(). Some whole applications will never use either of these methods.

Appropriate usage scenarios:

Usually update() or saveOrUpdate() are used in the following scenario:

* the application loads an object in the first session
* the object is passed up to the UI tier
* some modifications are made to the object
* the object is passed back down to the business logic tier
* the application persists these modifications by calling update() in a second session

saveOrUpdate() does the following:

* if the object is already persistent in this session, do nothing
* if another object associated with the session has the same identifier, throw an exception
* if the object has no identifier property, save() it
* if the object's identifier has the value assigned to a newly instantiated object, save() it
* if the object is versioned by a or , and the version property value is the same value assigned to a newly instantiated object, save() it
* otherwise update() the object

merge() is very different:

* if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
* if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance
* the persistent instance is returned
* the given instance does not become associated with the session, it remains detached

Hibernate flush() - syncing ORM cache to db state

Flushing the Session


Sometimes the Session will execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in memory. This process, called flush, occurs by default at the following points:


    *      before some query executions
    *      from org.hibernate.Transaction.commit()
    *      from Session.flush() 


The SQL statements are issued in the following order:


   1.      all entity insertions in the same order the corresponding objects were saved using Session.save()
   2.      all entity updates
   3.      all collection deletions
   4.      all collection element deletions, updates and insertions
   5.      all collection insertions
   6.      all entity deletions in the same order the corresponding objects were deleted using Session.delete() 


An exception is that objects using native ID generation are inserted when they are saved.


Except when you explicitly flush(), there are absolutely no guarantees about when the Session executes the JDBC calls, only the order in which they are executed. However, Hibernate does guarantee that the Query.list(..) will never return stale or incorrect data.


It is possible to change the default behavior so that flush occurs less frequently. The FlushMode class defines three different modes: only flush at commit time when the Hibernate Transaction API is used, flush automatically using the explained routine, or never flush unless flush() is called explicitly. The last mode is useful for long running units of work, where a Session is kept open and disconnected for a long time (see Section 11.3.2, “Extended session and automatic versioning”).


sess = sf.openSession();
Transaction tx = sess.beginTransaction();
sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state


Cat izi = (Cat) sess.load(Cat.class, id);
izi.setName(iznizi);


// might return stale data
sess.find("from Cat as cat left outer join cat.kittens kitten");


// change to izi is not flushed!
...
tx.commit(); // flush occurs
sess.close();


During flush, an exception might occur (e.g. if a DML operation violates a constraint).

Hibernate - load() vs get()

Difference between Hibernate - load() & get() methods:

 load() takes a class object and loads the state into a newly instantiated instance of that class in a persistent state.

Cat fritz = (Cat) sess.load(Cat.class, generatedId);
&
// you need to wrap primitive identifiers
long id = 1234;
DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );

load() will throw an unrecoverable exception, if there is no matching database row.
If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy. This is useful if you wish to create an association to an object without actually loading it from the database. It also allows multiple instances to be loaded as a batch if batch-size is defined for the class mapping.

If you are not certain that a matching row exists, you should use the get() method which hits the database immediately and returns null if there is no matching row.

Cat cat = (Cat) sess.get(Cat.class, id);
if (cat==null) {
    cat = new Cat();
    sess.save(cat, id);
}
return cat;

You can even load an object using an SQL SELECT ... FOR UPDATE, using a LockMode:
Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);

Any associated instances or contained collections will not be selected FOR UPDATE, unless you decide to specify lock or all as a cascade style for the association.

It is possible to re-load an object and all its collections at any time, using the refresh() method. This is useful when database triggers are used to initialize some of the properties of the object.

sess.save(cat);
sess.flush(); //force the SQL INSERT
sess.refresh(cat); //re-read the state (after the trigger executes)

Database BatchInsert - comparing JPA, Hibernate & Jdbc using Spring

I was trying batch inserting operation using JPA. I'm using Hibernate implementation under JPA.

Option1. Understood the vanilla JPA don't have batchInsert. But, according to Hibernate documentation, it supports insert but in specific format viz. 'INSERT INTO ... SELECT ... form is supported; not the INSERT INTO ... VALUES ... form.'
So, I tried the following:
public int batchInsertMessageList(List customerList) {
final String jpaQuery = "insert into Customer (tm.getCustomerId(),tm.getAddress()) " +
"select :tm tm from dual";
final Object[] customerArray = customerList.toArray();
Object ret = getJpaTemplate().execute( new JpaCallback() {
           public Object doInJpa(EntityManager em) throws PersistenceException {
               Query query = em.createQuery(jpaQuery);
               if (customerArray != null && customerArray.length > 0) {
                   for (Object obj : customerArray) {
                       //query.setParameter(parameterIndex++, obj);
                    query.setParameter("tm", obj);
                   }
               }
               return query.executeUpdate();
           }
       });
return (Integer) ret;
}


I'm using Hibernate jars in version 3.3. Unfortunately, it is giving following exception:
query must begin with SELECT or FROM: insert [insert into Customer (tm) select :tm tm from dual]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: query must begin with SELECT or FROM: insert [insert into Customer (tm) select :tm tm from dual]

If ever there is an error in my query, I cannot solve it to make work, as Hibernate says it don't support.

Option2:
I'm going for option2, directly updating using getJdbcTemplate(). This would deliver better performance :) but my deviation from JPA :(


Option3:
Using Hibernate directly as below:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
   Customer customer = new Customer(.....);
   session.save(customer);
   if ( i % 20 == 0 ) { //20, same as the JDBC batch size
       //flush a batch of inserts and release memory: to avoid OutOfMemoryException
       session.flush();
       session.clear();
   }
}

cURL commandline utility

A command line tool for getting or sending files using URL syntax.

Since cURL uses libcurl, it supports a range of common Internet protocols, currently including HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, LDAPS, DICT, TELNET, FILE, IMAP. POP3, SMTP and RTSP.

The name of the project is a play on 'Client for URLs', originally with URL spelled in uppercase to make it obvious it deals with URLs. The fact it can also be pronounced 'see URL' also helped; it works as an abbreviation for "Client URL Request Library" or the recursive version: "Curl URL Request Library". Distributed under the MIT License, cURL is free software.

Basic use of cURL involves simply typing curl at the command line, followed by the URL of the output to retrieve.

To retrieve the example.com homepage, type:

curl http://www.google.com.au

cURL defaults to displaying the output it retrieves to the standard output specified on the system (usually the terminal window). So running the command above would display the source-code of the google.com.au homepage.

cURL can write the output it retrieves to a file with the -o flag, thus:

curl -o example.html www.example.com

A practical example is the cURL for testing the twitter api like posting the tweet (status) as below:
curl -u username:password http://api.twitter.com/1/direct_messages.xml

Quickest way to download files:
eg: curl -o j2ee-6.pdf http://java.sun.com/javaee/6/docs/tutorial/doc/JavaEETutorial.pdf
PS: this is indeed a good doc ;)