使用XMLTYPE oracle 10g映射org.w3c.dom.Document

时间:2015-09-16 14:02:09

标签: hibernate xmltype

我已经创建了自己的用户类型来将org.w3c.dom.Document映射到XMLTYPE Oracle 10g。

这是我的jpa实体定义的一部分:

@Entity
@Table(name = "wzTable")
public class Business implements Serializable {

   // Other fields

    @Column(name ="xml_wizard", columnDefinition="XMLTYPE")
    @Type(type = "x.y.z.core.domain.technical.HibernateXMLType")
    private Document contenu;

    public Document getContenu() { return contenu; }
    public void setContenu(Document contenu) { this.contenu = contenu; }

   // Other getters & setters

这是我自己的用户类型定义的一部分:

public class HibernateXMLType implements UserType, Serializable {

    private static final long serialVersionUID = -5606979436742637062L;
    private static final int[] SQL_TYPES = new int[] { oracle.xdb.XMLType._SQL_TYPECODE };

    @Override
    public Object nullSafeGet(ResultSet rs, String[] values, SessionImplementor si, Object o) throws HibernateException, SQLException {
        XMLType xmlType = null; Document doc = null; OracleResultSet ors = null;
            try {                                      
                if (rs instanceof OracleResultSet) {
                    ors = (OracleResultSet) rs;
                } else {
                    throw new UnsupportedOperationException("ResultSet needs to be of type OracleResultSet");
                }
                op = ors.getOPAQUE(values[0]);
                if (op != null) {
                    xmlType = XMLType.createXML (op);
                }
                doc = xmlType.getDOM();
            }finally {
                if (null != xmlType) {
                    xmlType.close();
                }
            }
            return doc;
        }

        @Override
        public void nullSafeSet(PreparedStatement ps, Object o, int i, SessionImplementor si) throws HibernateException, SQLException {
            try {
                XMLType xmlType = null;
                if (o != null) {
                    xmlType = XMLType.createXML(ps.getConnection(), HibernateXMLType.domToString((Document) o));
                }
                ps.setObject(i, xmlType);
            }
            catch (Exception e) {
                throw new SQLException("Could not convert Document to String for storage");
            }
        }

        @Override
        public Object assemble(Serializable _cached, Object _owner) throws HibernateException {
            try {
                return HibernateXMLType.stringToDom((String) _cached);
            }
            catch (Exception e) {
                throw new HibernateException("Could not assemble String to Document", e);
            }
        }

        @Override
        public Serializable disassemble(Object _obj) throws HibernateException {
            try {
                return HibernateXMLType.domToString((Document) _obj);
            }
            catch (Exception e) {
                throw new HibernateException("Could not disassemble Document to Serializable", e);
            }
        }

        @Override
        public boolean equals(Object arg0, Object arg1) throws HibernateException {
            if (arg0 == null && arg1 == null) return true;
            else if (arg0 == null && arg1 != null ) return false;
            else return arg0.equals(arg1);
        }

        @Override public Object replace(Object _orig, Object _tar, Object _owner) { return deepCopy(_orig); }
        @Override public Object deepCopy(Object value) throws HibernateException { return value == null ? null : ((Document) value).cloneNode(true); }
        @Override public int[] sqlTypes() { return SQL_TYPES; }
        @Override public Class returnedClass() { return String.class; }
        @Override public int hashCode(Object _obj) { return _obj.hashCode(); }
        @Override public boolean isMutable() { return false; }

    public static String domToString(Document _document) throws TransformerException {
        DOMImplementation impl = _document.getImplementation();
        DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
        LSSerializer lsSerializer = implLS.createLSSerializer();
        lsSerializer.getDomConfig().setParameter("format-pretty-print", true);
        LSOutput lsOutput = implLS.createLSOutput();
        lsOutput.setEncoding("UTF-8");
        Writer stringWriter = new StringWriter();
        lsOutput.setCharacterStream(stringWriter);
        lsSerializer.write(_document, lsOutput);
        String result = stringWriter.toString();
        return result;
    }

    public static Document stringToDom(String xmlSource) throws SAXException, IOException, ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(new ByteArrayInputStream(xmlSource.getBytes("UTF-8")));
    }
}

我执行以下异常时会出现以下异常:XMLType.createXML(ps.getConnection(), HibernateXMLType.domToString((Document) o))

java.lang.ClassCastException: com.mchange.v2.c3p0.impl.NewProxyConnection cannot be cast to oracle.jdbc.OracleConnection
        at oracle.sql.OpaqueDescriptor.createDescriptor(OpaqueDescriptor.java:151)
        at oracle.xdb.XMLType.<init>(XMLType.java:540)
        at oracle.xdb.XMLType.createXML(XMLType.java:635)
        at x.y.z.core.domain.technical.HibernateXMLType.nullSafeSet(HibernateXMLType.java:64)
...

在调试HibernateXMLType.domToString((Document) o)上返回:

<?xml version="1.0" encoding="UTF-8"?>
<myObject>
    <id>15</id>
    <code>AZR</code>
    <label>QSDAZE</label>
    <date>2015-09-16+02:00</date>
    <type>SIMPLE_REQUIREMENT</type>
</myObject>

当我执行时: XMLType.createXML(ps.getConnection(), (Document) o) (没有HibernateXMLType.domToString()),我不会得到任何例外。新行插入“wzTable”。但“xml_wizard”字段为空。

你能帮助我,知道这个例外的真正起源是什么吗?

提前谢谢。

此致

1 个答案:

答案 0 :(得分:0)

此问题的真正原因是com.mchange.v2.c3p0.impl.NewProxyConnection无法转换为oracle.jdbc.OracleConnection。不幸的是,这个激活在stacktrace中被掩盖了。

解决方案位于this topic