Wednesday, December 28, 2011

Transaction Management with JBoss Seam + JPA (Hibernate) like Spring Framework

I'm a fan of using Spring framework for all my projects, but unfortunately on my current project, I have to add a module to an existing app already developed using JBoss Seam EJB3 and Hibernate, so this is what I did to work with the same model of ServiceImpl that Spring uses

This is the DAO (Existing) - I just added the save method
And this will be My Service (I will not include the Interfaces)

By doing this we have the same model of Tx Management - Just by adding the 1 annotation to the method!!! Cool Isn't it?
Also, in case that you want to make your Tx ReadOnly, just add this annotation to your method (also)
org.jboss.seam.annotations.ReadOnly


Unfortunately the documentation for JBoss Seam is really poor on this aspect, so If anybody finds anything that could be improved, please let me know)

Saturday, December 24, 2011

OneToMany Mapping

I faced this issue on August, let me explain you the situation, I had a Table called PURCHASE, with a 1:N Relationship with PURCHASE_MODULE and TRANSACTION tables
TRANSACTION >-----PURCHASE-----< PURCHASE_MODULE

First thing, How do I represent that using annotations (Hibernate):
Now what I want is each time I populate Purchase and set both List's (transactions and purchaseModules) and Invoke a SAVE for Purchase, the 3 tables will be impacted( there will be at least 3 INSERTs): purchaseDAO.save(purchase)
But this wasn't working as I expected, because no matter if I populated both ArrayList's (List) I never saw more than 1 Insert on my console.

Then the spark I was looking for! Inspiration came to me :P
On the Annotation @OneToMany there is an additional attribute I didn't include: cascade (The operations that must be cascaded to the target of the association)

On my case I don't care, so I just include ALL operations :P

Saturday, December 3, 2011

ClassCastException with Hibernate: org.hibernate.type.DateType cannot be cast to org.hibernate.type.VersionType

I ran into a weird error when starting a Seam App with JPA (Hibernate) on JBoss

2011-08-03 14:30:17,938 [main] ERROR [org.jboss.deployment.scanner.URLDeploymentScanner] Incomplete Deployment listing:

--- MBeans waiting for other MBeans ---
ObjectName: persistence.units:ear=mainsite.ear,jar=kaptest_domain.jar,unitName=commonDatabase
  State: FAILED
  Reason: java.lang.ClassCastException: org.hibernate.type.DateType cannot be cast to org.hibernate.type.VersionType
  I Depend On:
    jboss.jca:service=DataSourceBinding,name=jdbc.CommonTransactionDS
  Depends On Me:
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=AdobeMeetingDAO_Seam_Impl,service=EJB3
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=AdobeProductDAO_Seam_Impl,service=EJB3
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=AdobeUserDAO_Seam_Impl,service=EJB3
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=AverageRatingServiceImpl,service=EJB3
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=BookstoreProductServiceImpl,service=EJB3
    jboss.j2ee:ear=mainsite.ear,jar=kaptest_domain.jar,name=BookstoreSearchServiceImpl,service=EJB3
...
...
WHAT??? java.lang.ClassCastException: org.hibernate.type.DateType cannot be cast to org.hibernate.type.VersionType

Anyway, for some reason, hibernate reverse engineer puts the @Version annotation to fields called timestamp as it expects it to be of type java.sql.Timestamp
Unfortunatly, my property was of type java.util.Date which is incomaptible with the @Version annotation.
I removed the @Version and it worked!