Sunday, December 16, 2012

New features in JDBC 3.0

This article provides an introduction to the array of core new features available in JDBC 3.0. More specifically, the features ‘supporting save points’, ‘using parameter metadata’, ‘updating large objects’ and ‘auto generated keys’ are discussed. Wherever possible, to get a hang of it, relevant code samples have been provided in the respective sections.

Defining savepoints
It is possible to programmatically control the creation and releasing of save points through JDBC 3.0. But before doing it, one must check whether the underlying database supports the concepts of savepoints. Save points provide multiple-level-control of database commit or rollback operations within a single transaction. For example, if two unrelated database operations have to happen with a single transaction, these two save points can be created for the very purpose. Then based on various business conditions, commit/rollback can be done to any of these save points within the same transaction. To illustrate the usage, consider the following example: As seen from the above example, the program checks whether save points are supported by the target database by querying methods available in DatabaseMetadata. Note for save points are created by calling the method setSavePoint() defined on the Connection object. A save point can be given a name so that at a later point of time, a transaction can be made to commit or rollback based on the name. In the example code, to illustrate the usage of save point, we deliberately rollback the operation related to customer table, whereas, the changes made to country table are committed.

Parameter Metadata
Construction of queries for statements such as prepared statements might involve specifying dynamic values through ‘?’. Previously, there was no support for the tools or for the applications to identify the parameter information embedded in the queries. Now, support has been added to retrieve the parameter information that is passed to prepared statements. Please refer the below code that illustrates the usage: Auto Generated Keys
Execution of queries sometimes results in the automatic generation of fields or values for tables. The behavior is entirely dependent on the underlying database implementation. Previously, there was no standard mechanism for retrieving such information once the query is executed. Application developers are forced to use non-standard mechanisms for fetching information that happens outside the scope of query execution. For example, consider a table column containing a particular column, say ‘name’, and an equivalent upper column, let’s say ‘upper_name’. The value for the ‘upper_name’ will be automatically populated as soon as the value is populated for the ‘name’ column. This is one of the examples of auto generation feature and the newer specification supports this feature. Refer the code sample below: Note that, while executing the statement, the application has to provide indication to the underlying engine that, if any auto generation columns are applicable once the query is executed, those information have to be made available in the equivalent statement object. This is done through the method Statement.execute() where the second parameter specifies this option. Next, the method getGeneratedKeys() is added to the Statement object which returns a ResultSet containing the desired values. Because, this feature may or may not be supported by the database engine, the API supportsGeteGeneratedKeys() can be used to check the feature availability.

Updating clob/blob objects
The support to update clob objects is directly available on the Clob/Blob objects. The method updateClob() is added to the ResultSet object. Previously, there is no standard way to update large data objects. Note to ensure that this works and because the operation is defined on the ResultSet, the underlying ResultSet object should support updating the record. This is possible if the ResultSet is a flavor of CONCUR_UPDATABLE. Please refer the below code Conclusion
The new features in JDBC 3.0 have addressed most of the common problems that tools or developer community is encountering, thereby providing a unified way of solution. There are other minor updates done to JDBC 3.0, such as ‘configuring connection pools’, ‘adding of new data types as Boolean, Datalink, URL’ etc.

Saturday, November 3, 2012

Load Properties File with ClassLoader

For those who want to load a Properties file located in the classpath (could be the classpath of your server: Far from your artifact), this is how a Properties Files is loaded "like a Sir!"


Simple! Instead of using the traditional way
getClass().getResourceAsStream(propertiesFile);

By doing it in that way, we make sure the ClassLoader will look further into the classpath other than just look in the near surroundings :P

Monday, October 29, 2012

Interacting with Facebook using Java

If it's your first time interacting with Facebook, probably you haven't found many examples in Java, have you?
On my case I'm working with something really simple, I just need to create a simple app that will be configured as Canvas. There are 2 important steps in order to work with Facebook by using Canvas:

1. Authorization 
When Facebook calls your webpage (on my case a jhtml using SEAM - it could be a JSP as well), it will send through POST something called signed_request, for more details please read this The signed_request parameter is the concatenation of a HMAC SHA-256 signature string, a period (.), and a base64url encoded JSON object. It looks something like this (without the newlines):

vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso
.
eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsIjAiOiJwYXlsb2FkIn0

Just by receiving this parameter, it means that you (as facebook user) just authorized this app on your account, otherwise you'll get the classic mesage asking for your permission to use this app.

Next, we need to retrieve from the JSON object 2 parameters that we need to do the authentication: oauth_token and expires).
However, in order to play around with JSON object, we need to decode it, and this will do the trick: It's very important to use sun.misc.BASE64Decoder in order to avoid missing few characters when decoding with other classes. Belive me, this save you from a lot of headeaches. I'm a big fan of Commons, however, it didn't work out really good when decoding this JSON object. FYI, this is my method.

2. Authentication 
This step is really easy, because based on attributes oauth_token and expires, we have a to make a http call to https://graph.facebook.com/me in order to authenticate into FB.
As result of my http call, by using the JSON object returned, I'm able to get more details about this FB account, such as email, first name, last name, age, languages, among others. The next steps depend how deep you want to go.
Good luck!

Monday, September 24, 2012

Sorting a bean List with Commons

Nowadays whenever I surf the net, comparable interface is widely used to sort a List of objects. I am very sure it's the best approach, no doubt in that :)

However, if you want to sort in more than one place of your projects, I feel the code will be redundant. Am I right?

The alternate and the best solution is to use the Apache Commons Bean Utils


And this is how I did it:

Asceding order:
For ascending order, we should give the parameter alone. For instance, if we want sort by “endDate”. We should pass the parameter endDate to the BeanComparator class instance.


Reverse Order Sorting(Descending Order):
For descending order, we should give the parameter along with the instance of ReverseComparator class. For instance, if we want to sort by “firstName”. We should pass two parameters, such as the endDate and the instance of ReverseComparator class to the BeanComparator class.


Note:
Just keep in mind that your fild must be NON-NULL otherwise you'll get a pretty NPEx slap in your face.

Saturday, September 15, 2012

Keep parameter in session with Injection and Outjection

This time something kind of weird happened to me.

To be honest, each time I have to work with Jboss Seam, I always say to myself: "I wonder what kind of surprise waits for me this time". Because I'm a Spring Framework dude, and JBoss Seam documentation, well, is not really clear at all.

This is my case:
I have a page that receives a parameter from an external source, the page is displayed, user pays around with it, page gets refreshed a lot of times. And then, user submits page and everything and goes away, then is when I need that parameter received at the beginning. Because after the submit I have to pass it to another page which need it

The solution will be something like: come on dude! that's Servlets 101. Just set the parameter in the session the first time and that's it! Now the question is, what happens to that value set into the session? Because I want to use it on my pages.xml file to redirect the request to another page though!
And, very important, I want to write as less code as possible (by using Seam Annotations)

But better if we see some code:

The param received (passed by an external caller) is:
By doing this I'm keeping in Session this variable:
Very important to keep the parameter stored in session only once during page Creation!

This is my pages.xml, where I'm passing as param resume the value of my In/Outjected variable resumePersistentParam


Monday, August 20, 2012

Hibernate – Fetching Strategies Examples

Hibernate has few fetching strategies to optimize the Hibernate generated select statement, so that it can be as efficient as possible. The fetching strategy is declared in the mapping relationship to define how Hibernate fetch its related collections and entities.

Fetching Strategies

There are four fetching strategies
  • fetch-”join” = Disable the lazy loading, always load all the collections and entities.
  • fetch-”select” (default) = Lazy load all the collections and entities.
  • batch-size=”N” = Fetching up to ‘N’ collections or entities, *Not record*.
  • fetch-”subselect” = Group its collection into a sub select statement.

For detail explanation, you can check on the Hibernate documentation.

Fetching Strategies Examples

Here’s a “one-to-many relationship” example for the fetching strategies demonstration. A stock is belong to many stock daily records.

Lets explore how fetch strategies affect the Hibernate generated SQL statement.

Fetch=”Select” Or @Fetch(FetchMode.SELECT)

This is the default fetching strategy. it enabled the lazy loading of all it’s related collections.

Output:
Hibernate: 
    select ...from mkyong.stock
    where stock0_.STOCK_ID=?
 
Hibernate: 
    select ...from mkyong.stock_daily_record
    where stockdaily0_.STOCK_ID=?

Hibernate generated two select statements
1. Select statement to retrieve the Stock records -session.get(Stock.class, 114)
2. Select its related collections – sets.iterator()

Fetch=”Join” Or @Fetch(FetchMode.JOIN)

The “join” fetching strategy will disabled the lazy loading of all it’s related collections.

Output:
Hibernate: 
    select ...
    from
        mkyong.stock stock0_ 
    left outer join
        mkyong.stock_daily_record stockdaily1_ 
            on stock0_.STOCK_ID=stockdaily1_.STOCK_ID 
    where
        stock0_.STOCK_ID=?

Hibernate generated only one select statement, it retrieve all its related collections when the Stock is initialized. -session.get(Stock.class, 114)
1. Select statement to retrieve the Stock records and outer join its related collections.

Batch-Size=”10″ Or @BatchSize(Size = 10)

This ‘batch size’ fetching strategy is always misunderstanding by many Hibernate developers.

What is your expected result, is this per-fetch 10 records from collection? See the Output
Hibernate: 
    select ...from mkyong.stock
    where stock0_.STOCK_ID=?
 
Hibernate: 
    select ...from mkyong.stock_daily_record
    where stockdaily0_.STOCK_ID=?

The batch-size did nothing here, it is not how batch-size work. See this statement.
The batch-size fetching strategy is not define how many records inside in the collections are loaded. Instead, it defines how many collections should be loaded.
— Repeat N times until you remember this statement —

You want to print out all the stock records and its related stock daily records (collections) one by one.
No batch-size fetching strategy
Output:
Hibernate: 
    select ...
    from mkyong.stock stock0_
 
Hibernate: 
    select ...
    from mkyong.stock_daily_record stockdaily0_ 
    where stockdaily0_.STOCK_ID=?
 
Hibernate: 
    select ...
    from mkyong.stock_daily_record stockdaily0_ 
    where stockdaily0_.STOCK_ID=?
 
Keep repeat the select statements....depend how many stock records in your table.

If you have 20 stock records in the database, the Hibernate’s default fetching strategies will generate 20+1 select statements and hit the database.

1. Select statement to retrieve all the Stock records.
2. Select its related collection
3. Select its related collection
4. Select its related collection
….
21. Select its related collection
The generated queries are not efficient and caused a serious performance issue.


Enabled the batch-size=’10′ fetching strategy
Let see another example with batch-size=’10′ is enabled.
Output:
Hibernate: 
    select ...
    from mkyong.stock stock0_
 
Hibernate: 
    select ...
    from mkyong.stock_daily_record stockdaily0_ 
    where
        stockdaily0_.STOCK_ID in (
            ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
        )

Now, Hibernate will per-fetch the collections, with a select *in* statement. If you have 20 stock records, it will generate 3 select statements.
1. Select statement to retrieve all the Stock records.
2. Select In statement to per-fetch its related collections (10 collections a time)
3. Select In statement to per-fetch its related collections (next 10 collections a time)

With batch-size enabled, it simplify the select statements from 21 select statements to 3 select statements.

Fetch=”Subselect” Or @Fetch(FetchMode.SUBSELECT)

This fetching strategy is enable all its related collection in a sub select statement.

Output:
Hibernate: 
    select ...
    from mkyong.stock stock0_
 
Hibernate: 
    select ...
    from
        mkyong.stock_daily_record stockdaily0_ 
    where
        stockdaily0_.STOCK_ID in (
            select
                stock0_.STOCK_ID 
            from
                mkyong.stock stock0_
        )

With “subselect” enabled, it will create two select statements.
1. Select statement to retrieve all the Stock records.
2. Select all its related collections in a sub select query.



Conclusion The fetching strategies are highly flexible and a very important tweak to optimize the Hibernate query, but if you used it in a wrong place, it will be a total disaster (You're screwed dude!).


Monday, August 6, 2012

Delegated vs. Federated ID

It is important to understand that there are two different kind of single-sign-on solutions: delegated and federated. All the recent comparisons between OpenID and Facebook Connect failed to appreciate this fundamental difference. Facebook Connect is a delegated authentication service, while OpenID is a federated authentication service. They might offer very similar features, but they are very different.

A delegated solution means that one site is simply outsourcing its authentication needs to another pre-selected site. If your site uses Facebook Connect, you are delegating your authentication facilities to Facebook. Visitors to your site cannot use any other accounts, only accounts from the vendors you have pre-selected.

A federated solution means that visitors to your site can use any account they have, as long as it is compatible. It makes no difference to the site which account is being used, as long as it can interoperate. At its core, OpenID is a federated solution because its most important feature is the ability to use any OpenID account with any OpenID-enabled service.

Delegated authentication has a few drawbacks with respect to federated authentication. First, delegated authentication is inherently less secure than federated authentication. Even if encrypted, delegated authentication still sends the username and password (possibly even your network password) over the internet.

More Information...





Tuesday, July 31, 2012

OneToMany Relation with Non PK Columns

While goofing around @ my office my Boss told me about an issue he was facing while trying to map a OneToMany relation, but instead of using the classical PK on one side and FK on the other side, he wanted to define the relationship between tables with nonKey columns. I still don't know why but this situation reminded me when I was having a hard time playing with 1:1 relations.
Anyway the fact is that we need find a workaround for this, and as is well known if you don't define anything on Hibernate (Annotations), by default is going to use the default values, right?

My approach is simple, by just defining after the OneToMany annotation which columns I'll join, in order to get this Set. Probably my Child table has a PK which doesn't have anything to do with the column I'm using to do the join with the Parent (which is a valid scenario - and BTW is what's happening now) Why don't you give it a try! On my case one of colleagues tried and I got another satisfied customer ;)

Sunday, July 1, 2012

Logging Optimistic Concurrency Exceptions: org.hibernate.StaleObjectStateException and JBPM

When it is running in a cluster configuration, the jBPM synchronizes with the database by using optimistic locking. This means that each operation is performed in a transaction and if, at the end, a collision is detected, then the transaction in question is rolled back and has to be handled with a retry. This can cause org.hibernate.StateObjectStateException exceptions. When this happens, Hibernate will log the exceptions with a simple message: optimistic locking failed

Hibernate can also log the StateObjectStateException with a stack trace:
15:35:07,123 [DispatcherThread] ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.pvm.internal.job.TimerImpl#960071]
 at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1769)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2412)
 at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
 at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
 at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
 at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
 at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
 at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
 at org.jbpm.pvm.internal.tx.HibernateSessionResource.prepare(HibernateSessionResource.java:56)
 at org.jbpm.pvm.internal.tx.StandardTransaction.commit(StandardTransaction.java:107)
 at org.jbpm.pvm.internal.tx.StandardTransaction.complete(StandardTransaction.java:64)
 at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:57)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
 at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
 at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.acquireJobs(DispatcherThread.java:126)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.run(DispatcherThread.java:67)

To remove these stack traces, set the org.hibernate.event.def.AbstractFlushingEventListener class to FATAL. Do so in log4j by using the following configuration:
log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL

Remember, this exception will not affect your process execution!, you can ignore it :)

Source: http://docs.redhat.com/docs/en-US/JBoss_Enterprise_SOA_Platform/5/html/JBPM_Reference_Guide

Sunday, June 3, 2012

How to determine remote host on a RESTful Web Service

This is your Restfull service (At least one method):


As you can see, we don't have available the popular Request object, now what we can do is just to add another parameter to our method, and Listo!
@Context javax.servlet.http.HttpServletRequest request

Tuesday, May 1, 2012

JBPM and Clustering

I'll be precise: "Can JBPM be deployed in a Distributed environment?"
In other words, Can I deploy multiple instances of JBPM? (but I want only 1 JVM to control all the executions)

My answer is Yes, you can have that mode! Just need to disable the JobExecutor on the other instances (by altering the configuration file)


Otherwise, you'll see this exception on your consoles (If your JVM's fight for the JOB's):
15:51:55,379 [DispatcherThread] ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.pvm.internal.job.TimerImpl#385014]
 at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1769)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2412)
 at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
 at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
 at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
 at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
 at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
 at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
 at org.jbpm.pvm.internal.tx.HibernateSessionResource.prepare(HibernateSessionResource.java:56)
 at org.jbpm.pvm.internal.tx.StandardTransaction.commit(StandardTransaction.java:107)
 at org.jbpm.pvm.internal.tx.StandardTransaction.complete(StandardTransaction.java:64)
 at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:57)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
 at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
 at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.acquireJobs(DispatcherThread.java:126)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.run(DispatcherThread.java:67)

If you're too lazy to have specific configuration per JVM, and you don't care about those exceptions, you're good to go (because that exception does not impact the Execution of your process instance), however, you can hide it by using Log4J (I'll explain that in another post)

Friday, April 13, 2012

Delegate to Seam the management of my JBPM4 engine

The problem was really simple, it's just implement a Singleton without writing it :P

I have a simple class, but I just need it to be loaded when the app starts, because my class will load the JBPM4 engine (and that should be done only once - this process may take up to 4 seconds, which will make really slow the first request coming to my End-Point)
But let me write more code and less words
Just add to your class these tags
Define which method will be your Creation method (Initialization method), on my case the one which will load the Engine
Now the one which will Destroy your class (shutdown my JBPM4 engine) and release resources
and optionally, your Constructor

Simple, Isnt' it?
Now you can inject this Seam Component using Injection into another Seam Component, just like this


Wednesday, March 21, 2012

Fix javax.ejb.NoSuchEJBException: Could not find stateful bean on Seam and JBPM4

When I was using Google to look for answers to my problem, I found a lot of posts asking for a solution, just like me, but not a concrete answer (IMHO, JBoss has really poor documentation, compared with Spring, even their forums have less information), like this case

But I got a solution!!! (u_u)
Let me tell you my story...

On one of my Handlers I was using a ServiceImpl, just like this:
This is my ServiceImpl
And my getSeamComponentInstance method

As you can see, this doesn't have anything really weird, I just injecting a Bean into another class, and invoke one its methods! Simple (pure DI)

When you test it, it works! After it's been deployed, it works again, but...

After some period of inactivity... Boooom! The same line of code (the one where I invoke one of the methods of my ServiceImpl) was throwing an this
javax.ejb.NoSuchEJBException: Could not find stateful bean: 4sg5nl-4371oh-gsvwkdiv-1-gsvwst2j-1b
 at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:492)
 at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:443)
 at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:61)
 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
 at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
 at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
 at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
 at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
 at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
 at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:204)
 at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:117)
 at $Proxy81.afterTransactionRollback(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
 at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
 at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
 at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
 at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
 at org.javassist.tmp.java.lang.Object_$$_javassist_seam_5.afterTransactionRollback(Object_$$_javassist_seam_5.java)
 at org.jboss.seam.transaction.UTTransaction.rollback(UTTransaction.java:70)
 at org.jboss.seam.util.Work.workInTransaction(Work.java:68)
 at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
 at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
 at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
 at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
 at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
 at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
 at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
 at com.kaplan.service.impl.StudentDetailsServiceImpl_$$_javassist_seam_11.updateStudentDetails(StudentDetailsServiceImpl_$$_javassist_seam_11.java)
 at com.kaplan.jbpm.action.integration.jbpm4.UpdateStudentActionHandler.execute(UpdateStudentActionHandler.java:44)
 at org.jbpm.pvm.internal.wire.usercode.UserCodeActivityBehaviour.execute(UserCodeActivityBehaviour.java:42)
 at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)
 at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:672)
 at org.jbpm.pvm.internal.model.op.ExecuteActivityMessage.executeVoid(ExecuteActivityMessage.java:45)
 at org.jbpm.pvm.internal.job.MessageImpl.execute(MessageImpl.java:46)
 at org.jbpm.pvm.internal.job.MessageImpl.execute(MessageImpl.java:32)
 at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:79)
 at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:41)
 at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
 at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:50)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
 at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
 at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
 at org.jbpm.pvm.internal.jobexecutor.JobParcel.run(JobParcel.java:48)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
 at java.util.concurrent.FutureTask.run(FutureTask.java:138)
 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
 at java.lang.Thread.run(Thread.java:619)

WTF!!!

What!!! I'm not even using stateful beans!!!, I'm using plain POJO's not even stateless!
This is how it works Seam, when you inject a Component using Components.getInstance, you just get a Proxy, and that proxy references the REAL instance of the class you want to invoke, but for any weird reason, that instance it has been removed! Then, why the freaking Proxy points to a nonexistent object? No idea (u_u).

Let's force Seam to create a new instance if it doesn't exist and specify that I don't want a Stateful bean by passing the scope Stateless (you can try with another one, but Stateless seems to be working just fine) and this is it


And after 1 night of inactivity, the error was gone (one for the team!)

Sunday, February 5, 2012

StaleObjectStateException on JBPM4

When I was doing some testing to my recently implemented JBPM4 process, I faced a really ugly error, which ended abruptly my process :(

Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.pvm.internal.job.TimerImpl#17]

After researching on Jboss.org, I just found very few bread crumbs instead of the whole slice of bread:
StaleObjectException on Timer execution
My process was different, because mine was completely ASYNC, then I realize, what would happen if I make SYNC just the WAIT state (which was causing the problem) and keep ASYNC my other states. After my first test, I got what I was expecting :D

Wednesday, January 18, 2012

Migrating to JBPM4

As you well know, I was using for one of my projects JBPM3, but then I decided to to jump into something more stable and even cool! (which will give me more automatization and the ability to recover from server crashes - in other words, restart a process previously interrupted :) )

The API changed completely, some classes were renamed others were removed, methods are not the same, configuration is different, in a few words "It doesn't have any relation with the previous version"

Cons:


You won't be able to keep your logs or comments on your tables, no more Transient variables, no more stoping process due to Exceptions, no more suspend or resume process (using the API), poor history of each execution - but it really helps what you see (if you want more details, I recommend you to use wisely your Log4J), if you don't believe me, look at my base handler after I migrated


Pros:


Process definition is the same file which describes de Diagram spec (no more hidden files), configuration file is much simpler (the default params work really nice - It's almost ready for production out of the box), hibernate configuration is much easy to read, process could be started easily by using code (FEWER lines that in JBPM3), ASYNC process really work!, resume processes interrupted, you can define a business key for each execution - look into table JBPM4_HIST_PROCINST, Timer really works! - you'll see it on my process definition

This is how I started my process (due to my process is ASYNC, it doesn't wait until process is completed to return a response - which is great for Fire and Forget, obviously the first request will be the one which takes longer, because it will have to wait until everything is loaded but the next request will be super fast! - I've seen and Avg. of 70ms)

My process definition is cleaner and I really like it


Finally, let me show you a couple of Handlers, except for a few changes, I didn't change them a lot compared with my original JBPM3 code :) Cool beans!

Monday, January 9, 2012

Get Mail Merge in Gmail with This Google Docs Template


Want to send a bunch of emails personalized to each recipient? Sending mass emails is easy using Microsoft Word's mail merge, less so with Gmail. This Google Docs template, however, brings email merging to Gmail.
The free template is provided by consulting firm IT4SmallBusiness and includes in-depth instructions on the first tab. 
To start using this template, log into Gmail, open the MailMerge Google Docs template, and make a copy of it to your Google Docs account (under File > Make a copy...). Write your email on the second sheet, "Email text" and add the special fields like <>. Then go to the third sheet to add the data that will replace those special fields (e.g., the list of email recipients, their names, and other personalized info).
Note that you'll probably want to send your mass emails in batches, lest Google label you a spammer. Mail merge with Gmail would be handy for a lot of uses, from mailing clients/customers to sending party invitations with custom instructions, as the example shows.
MailMerge | via CNet