Archive for the ‘Hibernate’ Category

Hibernate: Single Table inheritance with annotation

Monday, April 26th, 2010
//// Principal.java
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.persistence.InheritanceType;
import javax.persistence.DiscriminatorType;

import org.hibernate.annotations.ForceDiscriminator;
@Entity
@Table(name ="principal")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "ctype", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue("p")
@ForceDiscriminator   //optional, useful in some occasions
public class Principal{
 ...
}

//// User.java
@Entity
@DiscriminatorValue("u")
@ForceDiscriminator //optional, useful in some occasions
public class User extends Principal {
  ...
}

//// Group.java
@Entity
@DiscriminatorValue("g")
@ForceDiscriminator //optional, useful in some occasions
public class Group extends Principal {
  ...
}

Hibernate: Annotation for join column custom column name

Sunday, April 4th, 2010
    @ManyToOne
    @JoinColumn(name = "company_id")
    public Company getCompany() {
        return company;
    }

Note that in this particular example, the @JoinColumn is optional since “company_id” is the hibernate default for getCompany

Java: Validation JSR303, Hibernate, JavaScript

Thursday, April 1st, 2010

Hibernate: annotations for PostgreSQL sequence id

Tuesday, March 30th, 2010
@Table(name = "mySchema.user")
@javax.persistence.SequenceGenerator(
    name="SEQ_STORE",
    allocationSize=1,
    sequenceName="mySchema.user_id_seq"
)
public class User {
....
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
    public Long getId() {
        return id;
    }
}

Hibernate: Database column name annotation

Wednesday, March 24th, 2010
@Column(name = "first_name")
public String getFirstName(){...

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