Category Archives: Hibernate

The annoying transaction journey

When moving to production environment, I encoutered some problems with a specific patch of IBM WAS (7.0.0.25). Then I discovered it was not really related to that particualr patch because that makes no sens. Later in the same week, when we went back to development environment,  we encountered the same errors… That was a bit wierd because the whole application was tested for more than one month without throwing anyone of those errors. Error List contains:

  • org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  • java.lang.IllegalArgumentException: Cannot convert value of type […] no matching editors or conversion strategy found
  • org.hibernate.TransactionException: Transaction not successfully started
  • [BlazeDs] serilization: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

At the same time, I discovered prezi and I wanted to test it. Here’s the result*:

 

* To integrate prezi presentation, please go here.

Advertisements

Spring/Hibernate Search on WAS 7: The Impossible Jar Combination



Instead of spending hours and hours in jars conflicts resolution, I suggest this combination which is working under Websphere:

Sping Framework 2.5.6 (with dependencies)
Hibernate 3.6.8
Hibernate Search 3.4.1
Lucene 3.1

This might be insignificant at first sight, but once you start getting

Error creating bean with name ‘propertyConfigurer’ defined in ServletContext resource [/WEB-INF/classes/webApplicationContext.xml]: Initialization of bean failed; nested exception is java.lang.NullPointerException (Solution)

and

Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org.hibernate.annotations.common.reflection.MetadataProvider(Solution)

you will start focusing on this listing :

antlr-2.7.6.jar
antlr-runtime-3.0.jar
aopalliance.jar
apache-solr-core-1.4.0.jar
asm-2.2.3.jar
asm-attrs.jar
asm.jar
backport-util-concurrent.jar
c3p0-0.9.1.jar
cfgatewayadapter.jar
cglib-2.2.jar
cglib-nodep-2.1_3.jar
commons-beanutils-1.8.3.jar
commons-beanutils-1.8.3-sources.jar
commons-beanutils-bean-collections-1.8.3.jar
commons-beanutils-core-1.8.3.jar
commons-codec-1.3.jar
commons-collections-3.1.jar
commons-dbcp.jar
commons-digester-2.0.jar
commons-digester-2.0-sources.jar
commons-discovery-0.4.jar
commons-fileupload-1.2.1.jar
commons-httpclient-3.0.1.jar
commons-io-1.4.jar
commons-lang.jar
commons-logging1.1.jar
commons-pool.jar
compass-2.2.0.jar
concurrent.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
flex-messaging-common.jar
flex-messaging-core.jar
flex-messaging-opt.jar
flex-messaging-proxy.jar
flex-messaging-remoting.jar
hibernate3.jar
hibernate-commons-annotations-3.2.0.Final.jar
hibernate-core-3.6.7.Final.jar
hibernate-entitymanager.jar
hibernate-search-3.4.1.Final.jar
iText-2.1.7.jar
jasperreports-3.7.2.jar
jasperreports-applet-3.7.2.jar
jasperreports-fonts-3.7.2.jar
jasperreports-javaflow-3.7.2.jar
javassist-3.9.0.GA.jar
javassist.jar
javax.persistence-2.0.0.jar//under websphere should be moved somewhere else (see http://bit.ly/JprRim)
jdbc2_0-stdext.jar
jgroups-2.8.0.GA.jar
jms.jar
jsr173_1.0_api.jar
jsr250-api.jar
jstl-1.2.jar
jta-1.1.jar
junit-4.4.jar
log4j-1.2.15.jar
lucene-analyzers-3.1.0.jar
lucene-core-3.1.0.jar
lucene-highlighter-3.1.0.jar
lucene-memory-3.1.0.jar
lucene-misc-3.1.0.jar
lucene-queries-3.1.0.jar
lucene-spellchecker-3.1.0.jar
mysql-connector-java-5.1.6-bin.jar
naming-resources.jar
ojdbc14.jar
poi-3.0.1-FINAL-20070705.jar
quartz.jar
richfaces-api-3.2.2-SNAPSHOT.jar
richfaces-impl-3.2.2-SNAPSHOT.jar
richfaces-ui-3.2.2-SNAPSHOT.jar
servlet-api.jar
slf4j-api-1.5.8.jar
slf4j-api.jar
slf4j-log4j12-1.5.0.jar
solr-common.jar
solr-core-1.4.0.jar
solr-solrj-1.4.0.jar
spring-aop.jar
spring-beans.jar
spring-context.jar
spring-context-support.jar
spring-core.jar
spring.jar
spring-jdbc.jar
spring-jms.jar
spring-orm.jar
spring-test.jar
spring-tx.jar
spring-web.jar
spring-webmvc.jar
spring-webmvc-portlet.jar
spring-webmvc-struts.jar
sqljdbc.jar
standard.jar
xalan.jar
xml-apis-1.0.b2.jar

Hope that helps and avoid humanity torture on jar conflicts resolution 😀

OrphanRemoval on WAS 7

WAS 7

While migrating from Apache Tomcat 6 to IBM Websphere 7, in a Spring Hibernate project, you will certainly face this error:

nested exception is java.lang.NoSuchMethodError: javax/persistence/OneToMany.orphanRemoval()Z

There are many posts on the net about it. But, when dealing with IBM Websphere, it seems to be a bit different from other environments. All the issue is about persistence. All you have to do is :

1) Move your javax.persistence-2.0.0.jar to ${WAS_INSTALL_DIR}/APPSERVER/java/jre/lib/ext

2) Open configuration console and navigate to Applications->Application Types-> Websphere Entreprise Applications -> ${youApplication}

3) Click on the link “Class loading and update detection”

Webpshere 7 project details

4) In Class Loader Order, select “Classes loaded with local class loader first (parent last)”

Class loading and update detection

5) Restart WAS 7 and check if the  javax.persistence-2.0.0.jar was correctly loaded.

Websphere view - lodade classes

In the WAS 7 Redbook(WebSphere Application Server V7 Administration and Configuration Guide), they say :

The default value for class loading mode is Classes loaded with parent class
loader first. This mode causes the class loader to first delegate the loading of
classes to its parent class loader before attempting to load the class from its local
class path. This is the default policy for standard Java class loaders.
If the class loading policy is set to Classes loaded with local class loader first
(parent last), the class loader attempts to load classes from its local class path
before delegating the class loading to its parent. This policy allows an application
class loader to override and provide its own version of a class that exists in the
parent class loader.

Looks like Websphere 7, then, contains old JPA definition, without OneToMany.OrphanRemoval (which is specified in JPA 2.0).

Mykong also suggested adding hibernate-jpa-2.0-api-1.0.0.Final.jar instead of javax.persistence-2.0.0.jar

Dynamic Hibernate Context Switching

 Dynamic context switching

Commonly, in a web application, only one database is needed.  On a J2EE application, the context defined in the webApplicationContext.xml is a static configuration file with one database(as far as I know). Furthermore, we need Associating entities through mapping files(hbm.xml) or with directly annotated classes.  But what if we need to create databases dynamically and switch between them?
This approach, dynamic DB creation, may have its drawbacks, but it may be a fatality in some cases.

Here is a demonstration of dynamic database creation and dynamic context switching.

First , we need the database creation script(create_script.sql).

CREATE TABLE 'Person' (
'id' int(11) NOT NULL auto_increment,
'name' varchar(20) default NULL,
'country' varchar(100) default NULL,
'adress' VARCHAR(20) default NULL,
PRIMARY KEY  ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And then create the database manually given its name:

java.sql.Connection connection = null;
try{
     connection=DriverManager.getConnection("[jdbc:mysql://dbserver:port]",user, pwd);
     java.sql.Statement stm=connection.createStatement();
     stm.executeUpdate(" CREATE DATABASE "+myDbName);
     String[] cmd = new String[]{"mysql", myDbName,
     "--user= "+user,
     "--password="+root ,
     "-e",
     "\"source  [fullPathto]\\create_script.sql\""
     };
     Runtime rt = Runtime.getRuntime>();
     Process proc = rt.exec(cmd);
     proc.waitFor();
}catch(Exception e){
     logger.fatal(e.getMessage());
}

I used MySql in this sample, thus, it should be in path environment variable. User and pwd variables are your server specific username and password. The fullPathTo is the full path directory to your create_table.script.

The database now created and populated, we have to make it accessible through a hibernate Context. I prefer using annotation for mapping but it can also been done with xml mapping files.  The context template looks like (hbtConf.xml):


<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <property name="connection.url">
      XXX
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>
    <property name="connection.driver_class">
      com.mysql.jdbc.Driver
    </property>
    <property name="dialect">
      org.hibernate.dialect.MySQLInnoDBDialect
    </property>
    <property name="current_session_context_class">thread</property>
    <property name="hibernate.show_sql">true</property>
    <property name="configurationClass">
      org.hibernate.cfg.AnnotationConfiguration
    </property>
    <mapping class="com.slm.entity.Person" />
</session-factory>
</hibernate-configuration>

Note that the “connection.url” was not set intentionally, it will be set later on the code while loading the context.

And here our person class :

@Entity
@Table(name = "person")
public class Organisme implements Serializable {
private static final long serialVersionUID = 10L;
@Id
@Basic(optional = false)
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;

@Column(name = "country")
private String country;

@Column(name = "adress")
private String adress;

//constructor, getters and setters, equal and hash …

}

Now, we’ll load the Annotated Configuration file, and set the connection.url property to fit our newly created database.

SessionFactory sf = null;
Session ss = null;
try{
    Configuration conf =new AnnotationConfiguration().
    configure("hbtConf.xml");
    conf.setProperty("hibernate.connection.url", serverRoot+myDbName);
    sf = conf.buildSessionFactory();
    ss = sf.getCurrentSession();
}catch (Exception e) {
    logger.error("session creation problem \nMSG:" +e.getMessage()+ "\nCause: " + e.getStackTrace().toString());
}

Setting the hibernate.connection.url manually to the new destination would select the intended database. You may have other properties to set manually if you’re using Lucene indexes for example:

   conf.setProperty("hibernate.search.default.indexBase", indexRootFolder + myContextualIndexDirectoryName);

That’s all for dynamic context switching.