-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Insert XMLType using UserType - basic doubt
PostPosted: Thu May 31, 2007 12:00 am 
Newbie

Joined: Tue May 01, 2007 5:48 pm
Posts: 6
Hi All,

Environment: Hibernate 3.x, Weblogic 8.1, JDK 1.4.x

I have the following table:
Code:
create table XMLROW_COLLECTED (
XMLROWID NUMBER primary key,
XMLCONTENT XMLTYPE);


Since there is no direct support for Oracle XMLType I followed the example listed at http://www.hibernate.org/405.html

Following are the important code snippets of the custom UserType class:

Code:
public class HibernateXMLType implements UserType, Serializable {
//  all other methods are ommitted at present for brevity

public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
         throws HibernateException, SQLException {
      XMLType xmlType = null;
      Document doc = null;
      try {         
         OPAQUE value = null;
         OracleResultSet ors = null;
         if (rs instanceof OracleResultSet) {
            ors = (OracleResultSet)rs;
         } else {
            throw new UnsupportedOperationException("ResultSet needs to be of type OracleResultSet");
         }
         
         value = ors.getOPAQUE(names[0]);
         xmlType = XMLType.createXML(value);
         Clob xmlClob = xmlType.getClobVal();
         doc = XMLUtils.createDocumentObject(xmlClob.getCharacterStream());
      }finally {
         if (null != xmlType) {
            xmlType.close();
         }
      }
      
      return doc;
   }

public void nullSafeSet(PreparedStatement stmt, Object value, int index)
         throws HibernateException, SQLException {
      
      XMLType xmlType = null;
      try {
         //If the value is null then set NULL and return
         if (null == value) {
            stmt.setNull(index, OracleTypes.OPAQUE, "SYS.XMLTYPE");
            return;
         }
         
         if (stmt instanceof OraclePreparedStatement) {
            xmlType = XMLType.createXML(stmt.getConnection(), XMLUtils.toXMLString((Document)value));
            OraclePreparedStatement oracleStmt = (OraclePreparedStatement)stmt;
            oracleStmt.setObject(index, xmlType);
         }else {
            throw new HibernateException("PreparedStatement object must be a OraclePreparedStatement");
         }
      }finally {
         if (null != xmlType) {
            xmlType.close();
         }
      }
   }


Here is the code for the model object:

Code:
public class XMLRowCollected implements Serializable {
   private Long xmlID;
   private HibernateXMLType xmlData;
   
   // Rest is getter/setter methods and default constructor
}


Here is the hbm.xml file:

Code:
<hibernate-mapping>
   <class name="com.goofy.test.xml.XMLRowCollected" table="TESTINGXMLTYPE">
      <id name="xmlID" unsaved-value="null" type="long">
         <column name="XMLROWID" not-null="true"/>
         <generator class="increment"/>
      </id>
      <property name="xmlData"
         type="com.goofy.test.xml.HibernateXMLType"
         column="XMLCONTENT"
         update="true"
         access="property"
         insert="true"/>
   </class>
</hibernate-mapping>



Before i move on - Is there anything wrong till now?



All i want to do is insert a row into XMLROW_COLLECTED table


I have some basic questions at this point:

1. Since the model class contains only 2 fields, and id and custom UserType, how will it hold the document object that will need to be available when nullSafeSet method gets called?
2. I guess the only way to insert a row will be to call
Code:
session.save(xmlRowCollectedInstance);
. If that is the case then how will i populate/pass the document object of an XML that needs to be stored?
3. When does nullSafeSet be called? I assume that whenever session.save() is called, Am i right?



INSERT INTO ... VALUES... is not supported in Hibernate and if i directly user PreparedStatement then nullSafeSet method does not get called. So i am stuck.

I tried to google and all i got is "how to code a custom UserType" class for supporting XMLType and how to retrieve the content. But was not able to find any code of how to use UserType class created to insert a row containing an XML into XMLType type column in an Oracle table.

I am a newbie and would really appreciate any help/pointers.

Thanks,
Madhav[/i]


Top
 Profile  
 
 Post subject: Re:Now getting a weird exception No dialect mapping found
PostPosted: Thu May 31, 2007 4:14 am 
Newbie

Joined: Tue May 01, 2007 5:48 pm
Posts: 6
I did the following changes:

Change the model bean class and replaced HibernateXMLType to Document. So now even though the mapping file maps the database field to HibernateXMLType but in the model it will have Document.

On doing this change a row is finally getting inserted when i do this:

Code:
XMLRowCollected bean = new XMLRowCollected();
bean.setXmlData(xmlDocument);
session.save(bean);


However when i try and retrieve the record just inserted it gives me an exception. Following is the code to retrieve:

Code:
Query query = session.createSQLQuery("select XMLCONTENT from XMLROW_COLLECTED where XMLROWID=1");
List results = query.list();


Exception that i get:

org.hibernate.MappingException: No Dialect mapping for JDBC type: 2007
at org.hibernate.dialect.TypeNames.get(TypeNames.java:56)
at org.hibernate.dialect.TypeNames.get(TypeNames.java:81)
at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:192)
at org.hibernate.loader.custom.CustomLoader.getHibernateType(CustomLoader.java:161)
at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:131)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1678)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2145)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)
at org.hibernate.loader.Loader.list(Loader.java:2024)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:111)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1655)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:164)
at com.goofy.test.xml.TestingXMLDBMain.main(TestingXMLDBMain.java:39)



Can anyone please point out what could be the problem?

Following is the Hibernate configuration:
Code:
        <property name="connection.url">jdbc:oracle:thin:@nlsun83:1532:ENID11</property>
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.pool_size">5</property>
        <property name="show_sql">true</property>



Thanks,
Madhav[/code]


Top
 Profile  
 
 Post subject: Oracle XMLType with Hibernate and Tomcat
PostPosted: Mon Jun 04, 2007 12:41 am 
Newbie

Joined: Sun Jun 03, 2007 11:10 pm
Posts: 2
This is an implementation of a CustomType for the Oracle XMLTYPE column. My platform is Tomcat rather than WebLogic.


Code:
...
<property name="xmlData" type="com.keys.dao.customtypes.HibernateXMLType">
            <column name="DYNAMIC_DATA" />
        </property>

...


Code:
package com.keys.dao.customtypes;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.OPAQUE;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class HibernateXMLType implements UserType {
   
    private static final Logger logger = Logger.getLogger(HibernateXMLType.class);
   
    public static final int[] SQL_TYPES = {Types.CLOB};

    public int[] sqlTypes() {
        return SQL_TYPES;
    }

    public Class returnedClass() {
        return java.lang.String.class;
    }

    public boolean equals(Object arg0, Object arg1) throws HibernateException {
        return arg0 == arg1;
    }

    public int hashCode(Object arg0) throws HibernateException {
        return arg0.hashCode();
    }

    public Object nullSafeGet( ResultSet rs, String [ ] names, Object arg2 ) throws HibernateException, SQLException {
       
        logger.debug(rs.getClass().getName());
       
        org.apache.tomcat.dbcp.dbcp.DelegatingResultSet drs = (org.apache.tomcat.dbcp.dbcp.DelegatingResultSet)rs;
        OracleResultSet ors = (OracleResultSet)drs.getInnermostDelegate();
        OPAQUE op = ors.getOPAQUE ( names[0] );
       
        if(op != null) {
            oracle.xdb.XMLType xt = oracle.xdb.XMLType.createXML ( op );
            return xt.getStringVal();
        } else {
            return null;
        }
       
        /*  This is the code to return document instead of just a plain string

        DOMReader reader = new DOMReader ();
        org.dom4j.Document document = reader.read ( xt.getDOM () );
        return document.getRootElement ();// getClobVal();
       
        */

    }



    public void nullSafeSet( PreparedStatement st, Object value, int index ) throws HibernateException, SQLException {

        String conName = "";
        OraclePreparedStatement ost = null;
       
        try {
       
            org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement dpstmt = (org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement)st;
            ost = (OraclePreparedStatement)dpstmt.getInnermostDelegate();

            Connection conn = ost.getConnection ();
            conName = conn.getClass ().getName ();

            // Get the oracle connection class for checking
            Class oracleConnectionClass = Class.forName ( "oracle.jdbc.driver.OracleConnection" );

            /*  This is code to insert a Document object rather than just a plain string
            if ( oracleConnectionClass.isAssignableFrom ( conn.getClass () ) ) {
                ost.setOPAQUE ( index, oracle.xdb.XMLType.createXML ( conn, ( (Element) value ).asXML () ) );// (OPAQUE)
            }
            */
           
            if(value != null) {
                if ( oracleConnectionClass.isAssignableFrom ( conn.getClass () ) ) {
                    ost.setOPAQUE ( index, oracle.xdb.XMLType.createXML(conn, (String)value));// (OPAQUE)
                } else {
                    throw new HibernateException ( "JDBC connection object must be a oracle.jdbc.OracleConnection !! "
                            + "Connection class is " + conn.getClass ().getName () );
                }
            }
           
         

        } catch ( SQLException e ) {
            logger.error("SQL Exception: " + e, e);
            throw e;
        } catch ( HibernateException e ) {
            logger.error("Hibernate Exception: " + e, e);
            throw e;
        } catch ( ClassCastException e ) {
            logger.error("Class Cast Exception:"  + e, e);
            // could not find the class with reflection
            throw new HibernateException ( "Unable to case a required class.\n" + e.getMessage () + "  -- value class:"
                    + conName );
        } catch ( ClassNotFoundException e ) {
            // could not find the class with reflection
            logger.error("ClassNotFoundException:"  + e, e);
            throw new HibernateException ( "Unable to find a required class.\n" + e.getMessage () );
        }
    }


...


}



One other issue that I had is the ojdbc14.jar was both in my server lib and my web app lib directories. This caused a ClassCastException when casting from org.apache.tomcat.dbcp.dbcp.DelegatingResultSet. Two of the same classes from different classloaders will do that.

Maybe this code will save someone else's weekend...


Top
 Profile  
 
 Post subject: Re: Oracle XMLType with Hibernate and Tomcat
PostPosted: Mon Jun 04, 2007 12:55 am 
Newbie

Joined: Tue May 01, 2007 5:48 pm
Posts: 6
zerglicious wrote:
This is an implementation of a CustomType for the Oracle XMLTYPE column. My platform is Tomcat rather than WebLogic.


Code:
...
<property name="xmlData" type="com.keys.dao.customtypes.HibernateXMLType">
            <column name="DYNAMIC_DATA" />
        </property>

...


Code:
package com.keys.dao.customtypes;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.OPAQUE;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class HibernateXMLType implements UserType {
   
    private static final Logger logger = Logger.getLogger(HibernateXMLType.class);
   
    public static final int[] SQL_TYPES = {Types.CLOB};

    public int[] sqlTypes() {
        return SQL_TYPES;
    }

    public Class returnedClass() {
        return java.lang.String.class;
    }

    public boolean equals(Object arg0, Object arg1) throws HibernateException {
        return arg0 == arg1;
    }

    public int hashCode(Object arg0) throws HibernateException {
        return arg0.hashCode();
    }

    public Object nullSafeGet( ResultSet rs, String [ ] names, Object arg2 ) throws HibernateException, SQLException {
       
        logger.debug(rs.getClass().getName());
       
        org.apache.tomcat.dbcp.dbcp.DelegatingResultSet drs = (org.apache.tomcat.dbcp.dbcp.DelegatingResultSet)rs;
        OracleResultSet ors = (OracleResultSet)drs.getInnermostDelegate();
        OPAQUE op = ors.getOPAQUE ( names[0] );
       
        if(op != null) {
            oracle.xdb.XMLType xt = oracle.xdb.XMLType.createXML ( op );
            return xt.getStringVal();
        } else {
            return null;
        }
       
        /*  This is the code to return document instead of just a plain string

        DOMReader reader = new DOMReader ();
        org.dom4j.Document document = reader.read ( xt.getDOM () );
        return document.getRootElement ();// getClobVal();
       
        */

    }



    public void nullSafeSet( PreparedStatement st, Object value, int index ) throws HibernateException, SQLException {

        String conName = "";
        OraclePreparedStatement ost = null;
       
        try {
       
            org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement dpstmt = (org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement)st;
            ost = (OraclePreparedStatement)dpstmt.getInnermostDelegate();

            Connection conn = ost.getConnection ();
            conName = conn.getClass ().getName ();

            // Get the oracle connection class for checking
            Class oracleConnectionClass = Class.forName ( "oracle.jdbc.driver.OracleConnection" );

            /*  This is code to insert a Document object rather than just a plain string
            if ( oracleConnectionClass.isAssignableFrom ( conn.getClass () ) ) {
                ost.setOPAQUE ( index, oracle.xdb.XMLType.createXML ( conn, ( (Element) value ).asXML () ) );// (OPAQUE)
            }
            */
           
            if(value != null) {
                if ( oracleConnectionClass.isAssignableFrom ( conn.getClass () ) ) {
                    ost.setOPAQUE ( index, oracle.xdb.XMLType.createXML(conn, (String)value));// (OPAQUE)
                } else {
                    throw new HibernateException ( "JDBC connection object must be a oracle.jdbc.OracleConnection !! "
                            + "Connection class is " + conn.getClass ().getName () );
                }
            }
           
         

        } catch ( SQLException e ) {
            logger.error("SQL Exception: " + e, e);
            throw e;
        } catch ( HibernateException e ) {
            logger.error("Hibernate Exception: " + e, e);
            throw e;
        } catch ( ClassCastException e ) {
            logger.error("Class Cast Exception:"  + e, e);
            // could not find the class with reflection
            throw new HibernateException ( "Unable to case a required class.\n" + e.getMessage () + "  -- value class:"
                    + conName );
        } catch ( ClassNotFoundException e ) {
            // could not find the class with reflection
            logger.error("ClassNotFoundException:"  + e, e);
            throw new HibernateException ( "Unable to find a required class.\n" + e.getMessage () );
        }
    }


...


}



One other issue that I had is the ojdbc14.jar was both in my server lib and my web app lib directories. This caused a ClassCastException when casting from org.apache.tomcat.dbcp.dbcp.DelegatingResultSet. Two of the same classes from different classloaders will do that.

Maybe this code will save someone else's weekend...



Could you also post the code for th model bean and the invoking code?
That will clarify a lot of things.

I am trying to both insert and fetch using the setup and i am having problems. Does your code work when used to fetch rows with XMLType and insert rows with XMLType? If yes then could you make relevant code available?

Thanks a lot for your contribution.

Regards,
Madhav


Top
 Profile  
 
 Post subject: Bean Code
PostPosted: Mon Jun 04, 2007 1:05 am 
Newbie

Joined: Sun Jun 03, 2007 11:10 pm
Posts: 2
There are many more properties to this class but here are is the relevant one.


Code:
public class ModelLocale  {

public String getXmlData() {
        return xmlData;
    }

    public void setXmlData(String xmlData) {
        this.xmlData = xmlData;
    }


}



Here is the code that fetches a ModelLocale object:

Code:
   /**
    * Finds a model's detailed information by model id
    */
   public ModelLocale findById(ModelLocaleId id) throws DAOException {
      logger.debug("Entering findById() for id = " + id);

      Session session = sessionFactory.openSession();
      Transaction tx = null;

      ModelLocale model = null;

      try {
         tx = session.beginTransaction();

         model = (ModelLocale) session.get(ModelLocale.class, id);

         tx.commit();
      } catch (Exception e) {
         logger.error("Database error shile searchin for model id = " + id + ": " + e);
         if (tx != null)
            tx.rollback();
         throw new DAOException(e);
      } finally {
         session.close();
      }

      return model;
   }
[/code]


Top
 Profile  
 
 Post subject: Oracle XMLType issue
PostPosted: Thu Jun 07, 2007 8:28 am 
Newbie

Joined: Thu Jun 07, 2007 8:06 am
Posts: 1
I am trying the same example as mentioned by madhav.I have tried putting the field value xmlData in XMLRowCollected as String as well as
org.dom4j.Element and org.dom4j.Document.But in all the cases while inserting a row when the setNullSafe method is getting invoked the value argument always has the null value.I cant figure out,where is the mistake.Can any body point out what can be the reason behind it?

I am attaching the code ant the configs.

public class XMLRowCollected implements Serializable{
private int xmlID;
private String xmlData;
// getter setter methods
}

mapping file ----

<hibernate-mapping package="com.surya.example">
<class name="XMLRowCollected" table="XMLROW_COLLECTED">
<id name="xmlID" unsaved-value="null" type="int">
<column name="XMLROWID" not-null="true"/>
</id>
<property name="xmlData"
type="com.surya.hibernate.HibernateXMLType"
column="XMLCONTENT"
update="true"
access="property"
insert="true"/>
</class>
</hibernate-mapping>

HibernateXMLType class ---

public void nullSafeSet( PreparedStatement st, Object value, int index ) throws HibernateException, SQLException {
String conName = "";
try {
OraclePreparedStatement ost = null;
if ( st instanceof OraclePreparedStatement ) {
ost = (OraclePreparedStatement) st;
} else {
throw new HibernateException ( "PreparedStatement object must be a OraclePreparedStatement !! "
+ "Connection class is " + st.getClass ().getName () );
}
Connection conn = st.getConnection ();
conName = conn.getClass ().getName ();

Class oracleConnectionClass = Class.forName ( "oracle.jdbc.driver.OracleConnection" );
System.out.println("value -- "+value);

if ( oracleConnectionClass.isAssignableFrom ( conn.getClass () ) ) {
ost.setOPAQUE ( index, oracle.xdb.XMLType.createXML ( conn,(String)value ) );// (OPAQUE)
} else {
throw new HibernateException ( "JDBC connection object must be a oracle.jdbc.OracleConnection !! "
+ "Connection class is " + conn.getClass ().getName () );
}



The value parameter is always coming as null.


Top
 Profile  
 
 Post subject: HibernateXMLType vs Jboss4.2.2
PostPosted: Thu Oct 02, 2008 12:59 pm 
Newbie

Joined: Thu Oct 02, 2008 5:32 am
Posts: 2
Hi all,

i'm trying to use the HibernetXMLType ina an application deployed under jboss Application Server 4.2.2 and i have big problem casting the given ResultSet to OracleResultSet.

Following mu custom code:

public Object nullSafeGet( ResultSet rs, String [ ] names, Object arg2 )
throws HibernateException, SQLException
{
XMLType xmlType = null;
Document doc = null;
try {
OPAQUE op = null;
System.out.println("############################## rs: "+rs); // here i can see: oracle.jdbc.driver.OracleResultSetImpl
System.out.println("############################## RUNTIME CLASS: "+rs.getClass().getName());// here i can see: org.jboss.resource.adapter.jdbc.WrappedResultSet
ResultSet underlyingRs = null;
get
try {
org.jboss.resource.adapter.jdbc.WrappedResultSet wrappedRs = (org.jboss.resource.adapter.jdbc.WrappedResultSet)rs;
underlyingRs = wrappedRs.getUnderlyingResultSet();
} catch (ClassCastException e) {
// My Exception
e.printStackTrace();
}
OracleResultSet ors = null;
if (underlyingRs instanceof OracleResultSet) {
ors = (OracleResultSet)rs;
} else {
throw new UnsupportedOperationException("ResultSet needs to be of type OracleResultSet");
}
op = ors.getOPAQUE(names[0]);
if(op != null) {
xmlType = XMLType.createXML ( op );
}
doc = xmlType.getDOM();
}finally {
if (null != xmlType) {
xmlType.close();
}
}
return doc;
}

i have tryed to customize this method because using the original one the given ResultSet is not recognized as instance of OracleResultSet and obviously nothing work...

Someone can please help me?

if my explanation was not clear let's tell and i will try to give more details.

Cheers,

Carlo


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.