Archive for the ‘Hibernate’ Category

Hibernate: Config properties, c3p0 and disable the cache level

Thursday, July 30th, 2009
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost/dbname?useUnicode=true&ampcharacterEncoding=UTF8
hibernate.connection.username=username
hibernate.connection.password=pwd

#only if you use the current session
hibernate.current_session_context_class=thread
hibernate.connection.release_mode=on_close

#disable the second level cache
hibernate.cache.use_second_level_cache=false
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect

#do not forget the provider_class to set C3P0. No more auto detect in Hibernate 3.0.0+
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800

Hibernate: Single table inheritance annotations

Sunday, July 19th, 2009
@Entity
@Table(name = "employee")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "ctype", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue("e")
@ForceDiscriminator //optional
public class Employee{
...
}

And the subclass would be like

@Entity
@DiscriminatorValue("m")
public class Manager extends Employee{
....
}

Hibernate: Store Enum as String

Sunday, July 19th, 2009

Just add the @Enumerated(EnumType.STRING)

@Enumerated(EnumType.STRING)
public Type getType() {
    return type;
}

Hibernate: Supporting Spring DataSourceTransactionManager (and @Transactional) programmatically with SessionFactoryUtils

Sunday, July 5th, 2009

Here is the minimum code to support DataSourceTransactionManager thread bound session  (similar to OpenSessionInViewInterceptor).

For each thread:

public void beginThreadSession(SessionFactory sessionFactory){

  Session session = SessionFactoryUtils.getSession(sessionFactory, true);
  TransactionSynchronizationManager.bindResource(sessionFactory,
                                               new SessionHolder(session));

}
public void endThreadSession(SessionFactory sessionFactory){

  SessionHolder sessionHolder =
    (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
  SessionFactoryUtils.closeSession(sessionHolder.getSession());

}

DataSourceTransactionManager will pickup the thread bound session with SessionFactoryUtils. The trick is calling the “un/bindResource” methods. This set one session for all your requests and transactions for a given thread (and use the @transactional if you have configured it as follow).

<aop:config proxy-target-class="true"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
    <property name="configLocation" value="config/hibernate.cfg.xml"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

Obviously, this is the strict minimum code (good of unit testing for example). For Web App, use the OpenSessionInViewInterceptor.

<bean id="openSessionInView"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory"/>
    <!-- optional
    <property name="flushModeName" value="FLUSH_NEVER" />
    -->
</bean>

Hibernate: org.hibernate.WrongClassException … instanceAlreadyLoaded

Monday, May 4th, 2009

Hibernate inheritance and relationship could lead to the following exception:

Caused by: org.hibernate.WrongClassException: Object with id: 3 was not of the
specified subclass...
...
        at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1267)
        at org.hibernate.loader.Loader.getRow(Loader.java:1219)
        at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
        at org.hibernate.loader.Loader.doQuery(Loader.java:724)
...

Putting @ForceDiscriminator near the @DiscriminatorValue(..) of your respective classes might solve the problem.
See Hibernate Annotation Doc

Java: c3p0.ComboPooledDataSource broken pipe Error With MySQL

Monday, April 13th, 2009

This usually happen when the client connection pool maintained connection longer than the database connection. Fix: set the maxIdleTime property:

 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="driverClass" value="${db.driverClass}" />
  <property name="jdbcUrl" value="${db.jdbcUrl}" />
  <property name="user" value="${db.user}" />
  <property name="password" value="${db.password}" />
  <!-- 1/2 hr. MySQL server default connection timeout is 43200 (12hrs) -->
  <property name="maxIdleTime" value="1800" />
 </bean>

Information Source: Broken pipe

Hibernate (annotation): Error: TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

Friday, March 27th, 2009

If you get an error like this one

Hibernate: Error: TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing..

It is probably because you did not annotate your ManyToOne with the Hibernate SAVE_UPATE Cascade annotation:

@ManyToOne()
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public Category getCategory() {
        return category;
}

Note, putting only

@ManyToOne(cascade = {CascadeType.MERGE,CascadeType.PERSIST})
public Category getCategory() {

Will not resolve the issue.

Java: Hibernate 3.4 and SLF4J Impl Class not found and Singleton error

Friday, March 20th, 2009

Hibernate 3.4 does not have a SLF4J implementation, and if you download the latest implementation from http://www.slf4j.org/download.html you will get an imcompatible impl version (1.5.6 impl with the 1.5.2 api from Hibernate).

Just do the following:

  1. Remove all slf4j*.jar from your lib.
  2. Add the the latest sfl4j-api (i.e. slf4j-api-1.5.2)
  3. Add the latest impl slf4j-log4j12-1.5.6-.jar

NOTE: If you use Hibernate, make sure to use the slf4j-log4j*.jar, otherwise, changing the log4j.properties will have no effect. (see Turn off logging from log4j and slf4j)