Announcement Announcement Module
Collapse
No announcement yet.
Spring - Hibernate CLOB/Transaction Issues Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring - Hibernate CLOB/Transaction Issues

    Hello,

    I have been using spring for a little while, but I am very new to using hibernate. Sorry if this question has been asked numerous times, but I can't quite seem to get things working.

    I am having trouble persisting clobs through hibernate wrapped in spring to a back-end Oracle database. What I would like to do is treat the blob as a string in my business objects and automatically transform it to a CLOB when reading/writing from the database.

    I can read CLOBS from the database without a problem with this method. In a previous version of the code, I treated the clobs as varchars in the database, and I was able to write to the database; however, I wasn't able to read the columns.

    My environment is...
    spring1.2-rc1
    hibernate3.0.beta4
    The Ojdbc14.jar implementing the Oracle JDBC Driver version - 9.0.2.0.0 driver
    Oracle9i database

    Here is a simplified version of my code and configuration files.

    My hibernate object.
    public FavoriteReport
    {
    private int id;
    private String description;

    public void setDescription(String pValue) { this.description = pValue; }
    public void setId(int pValue) { this.id = pValue; }
    public int getId() { return this.id; }
    public String getDescription() { return this.description; }
    }

    I also have a second object FavoriteReportDTO which essentially has the same fields as the hibernate object. The DTO object is passed from the middle-tier to the web-tier.

    I have a DAO object defined like this...

    public class FavoriteReportDAOImpl extends HibernateDaoSupport implements FavoriteReportDAOIF
    {
    public FavoriteReportDTO get(long id)
    {
    FavoriteReport mBaseReport = (FavoriteReport)getHibernateTemplate().get(Favorit eReport.class, new Integer(id));

    FavoriteReportDTO mReport = convertToDTO(mBaseReport);
    }

    public void create(FavoriteReportDTO pReport)
    {
    FavoriteReport mReport = convertToHib(pReport);
    getHibernateTemplate().saveOrUpdate(mReport);
    }
    }

    The convertToDTO and convertToHib transform a hibernate object to a DTO object and vice versa.

    My Business Logic component looks like this...
    public class FavoriteReportBLImpl implements FavoriteReportBLIF
    {
    FavoriteReportDAOIF dao; // set through injection

    public void create(Map pParams)
    {
    FavoriteReportDTO mReport = createFromParams(pParams);

    this.dao.create(mReport);
    }

    public FavoriteReportDTO get(long id)
    {
    return this.dao.get(id);
    }
    }

    My hibernate configuration file looks like this...
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="FavoriteReport" table="MOR_FAVORITE">
    <id name="id" type="java.lang.Integer" unsaved-value="0">
    <column name="favorite_id" not-null="true" unique="true" sql-type="number"/>
    <generator class="native">
    <param name="sequence">MOR_FAVORITE_SEQ</param>
    </generator>
    </id>
    <property name="description" type="org.springframework.orm.hibernate3.support.C lobStringType">
    <column name="description" not-null="false" sql-type="clob"/>
    </property>
    </class>
    </hibernate-mapping>

    My spring configuration file looks like this...
    <beans>

    <!-- reference to database repository -->
    <bean id="morRepository" class="org.springframework.jndi.JndiObjectFactoryB ean">
    <property name="jndiName"><value>dbhabds</value></property>
    </bean>

    <!-- Hibernate Session Factory with associated support files -->
    <bean id="morRepoHibSessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
    <property name="dataSource"><ref local="morRepository"/></property>
    <property name="mappingResources">
    <list>
    <value>mor_favorite.hbm.xml</value>
    </list>
    </property>
    <property name="lobHandler">
    <ref bean="oracleLobHandler"/>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.Orac le9Dialect</prop>
    </props>
    </property>
    </bean>

    <!-- Used to open and close the session -->
    <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.Hibernat eInterceptor">
    <property name="sessionFactory">
    <ref bean="morRepoHibSessionFactory"/>
    </property>
    </bean>

    <!-- LOB Handler for Oracle JDBC Drivers -->
    <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.Oracle LobHandler">
    <property name="nativeJdbcExtractor"><ref local="nativeJdbcExtractor"/></property>
    </bean>

    <!-- Native JDBC Extractor -->
    <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc .SimpleNativeJdbcExtractor" lazy-init="true">
    </bean>

    <!-- Our Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
    <property name="dataSource"><ref local="morRepository"/></property>
    <property name="sessionFactory"><ref local="morRepoHibSessionFactory"/></property>
    </bean>

    <!-- DAO Configuration; we need to wrap the methods in a hibernate interceptor to allow us to lazy load references -->
    <bean id="favoriteDao" class="org.springframework.aop.framework.ProxyFact oryBean">
    <property name="target"><ref bean="favoriteDaoTarget"/></property>
    <property name="proxyInterfaces">
    <value>com.fmr.cfit.mor.fav.dao.FavoriteReportDAOI F</value>
    </property>
    <property name="interceptorNames">
    <list>
    <value>hibernateInterceptor</value>
    </list>
    </property>
    </bean>

    <bean id="favoriteDaoTarget" class="com.fmr.cfit.mor.fav.dao.HibFavoriteReportD AOImpl">
    <property name="sessionFactory"><ref local="morRepoHibSessionFactory"/></property>
    </bean>

    <!-- Specific Data Manipulator -->
    <bean id="favBizLogicTarget" class="com.fmr.cfit.mor.fav.biz.FavoriteReportBLIm pl">
    <property name="dao"><ref local="favoriteDao"/></property>
    </bean>
    <bean id="favBizLogic" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="target"><ref local="favBizLogicTarget"/></property>
    <property name="transactionAttributes">
    <props>
    <prop key="create">PROPAGATION_REQUIRED</prop>
    <prop key="get">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>
    </beans>


    When I run this, I get a concurrency exception thrown on the create method if I have the create method registered in the transaction manager. My guess is that this is occuring because of the hibernate interceptor.

    java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.j ava:782)
    at java.util.HashMap$EntryIterator.next(HashMap.java: 824)
    at java.util.AbstractMap.toString(AbstractMap.java:58 6)
    at java.lang.String.valueOf(String.java:2131)
    at java.lang.StringBuffer.append(StringBuffer.java:37 0)
    at org.hibernate.engine.PersistenceContext.toString(P ersistenceContext.java:956)
    at java.lang.String.valueOf(String.java:2131)
    at java.lang.StringBuffer.append(StringBuffer.java:37 0)
    at org.hibernate.impl.SessionImpl.toString(SessionImp l.java:1417)
    at java.lang.String.valueOf(String.java:2131)
    at java.lang.StringBuffer.append(StringBuffer.java:37 0)
    at org.springframework.orm.hibernate3.HibernateTransa ctionManager.doCommit(HibernateTransactionManager. java:466)


    If I turn off the transaction management on that method, I get the following error...

    org.springframework.dao.DataAccessResourceFailureE xception: Could not create Oracle LOB; nested exce
    ption is java.lang.ClassCastException: null
    java.lang.ClassCastException
    at oracle.jdbc.driver.OracleConnection.unwrapComplete ly(OracleConnection.java:5090)
    at oracle.jdbc.driver.OracleConnection.physicalConnec tionWithin(OracleConnection.java:5141)
    at oracle.sql.CLOB.createTemporary(CLOB.java:1009)
    at oracle.sql.CLOB.createTemporary(CLOB.java:956)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at org.springframework.jdbc.support.lob.OracleLobHand ler$OracleLobCreator.prepareLob(OracleL
    obHandler.java:378)
    at org.springframework.jdbc.support.lob.OracleLobHand ler$OracleLobCreator.createLob(OracleLo
    bHandler.java:328)
    at

    Any help in resolving this would be greatly appreciated,

    Thanks,

    Matt

  • #2
    No Replies?

    Hello,

    I was hoping that someone would still post some ideas for what was happening.

    If not, is the question too general and I need to specify more detail? Is it so obvious that I can find the answer with a little more digging through the archives?

    My current idea to resolve this would be to rip Hibernate and/or Spring out of the system and go with an all stored procedure solution. However, I would like to avoid that if possible.

    Thanks for any help anyone can provide,

    Matt

    Comment


    • #3
      Does anyone have any ideas?

      Comment


      • #4
        Check the datatype of the "description" field - i think you would need to create a CLOB out of the String before you can save it.

        So in the method where you convert to Hib you would do something like hib_object.setDescription(Hibernate.createClob(" "));

        Don't know if this was too obvious to be the issue, but good luck with it anyhow..

        Comment

        Working...
        X