zl程序教程

您现在的位置是:首页 >  后端

当前栏目

基于不同版本Hibernate的OracleXmlType处理详解编程语言

hibernate编程语言 详解 处理 基于 版本 不同
2023-06-13 09:11:51 时间

需要从Oracle数据库中查出xmltype类型的数据,并且与pojo类中的org.w3c.dom.Document类型的字段对应。由于Hibernate4(4.3.11.Final)和Hibernate5(5.3.7.Final)对于org.hibernate.usertype.UserType接口的nullSafeGet和nullSafeSet方法的形参定义不同,所以在Hibernate4和Hibernate5下对应Oracle的xmltype数据的OracleXmlType类的定义也不同。

Hibernate4项目

DatDocument.java

package com.jake.hib4.pojo; 

import lombok.Data; 

import org.hibernate.annotations.Type; 

import org.w3c.dom.Document; 

import javax.persistence.*; 

@Data 

@Entity 

@Table(name = "DAT_DOCUMENT") 

public class DatDocument { 

 @Id 

 @Column(name = "APP_ID", unique = true, nullable = false, length = 100) 

 private String datDocumentId; 

 @Type(type = "com.jake.hib4.hiextype.OracleXmlType") 

 @Column(name = "DOCUMENT_DATA", columnDefinition = "XMLTYPE") 

 private Document document; 

在Hibernate4的项目中对于OracleXmlType的定义如下:
OracleXmlType.java

// 

// Source code recreated from a .class file by IntelliJ IDEA 

// (powered by Fernflower decompiler) 

package com.jake.hib4.hiextype; 

import java.io.ByteArrayInputStream; 

import java.io.IOException; 

import java.io.Serializable; 

import java.io.StringWriter; 

import java.sql.Connection; 

import java.sql.PreparedStatement; 

import java.sql.ResultSet; 

import java.sql.SQLException; 

import javax.xml.parsers.DocumentBuilder; 

import javax.xml.parsers.DocumentBuilderFactory; 

import javax.xml.parsers.ParserConfigurationException; 

import javax.xml.transform.Transformer; 

import javax.xml.transform.TransformerException; 

import javax.xml.transform.TransformerFactory; 

import javax.xml.transform.dom.DOMSource; 

import javax.xml.transform.stream.StreamResult; 

import oracle.xdb.XMLType; 

import org.apache.commons.lang3.StringUtils; 

import org.hibernate.HibernateException; 

import org.hibernate.engine.spi.SessionImplementor; 

import org.hibernate.usertype.UserType; 

import org.slf4j.Logger; 

import org.slf4j.LoggerFactory; 

import org.w3c.dom.Document; 

import org.xml.sax.SAXException; 

public class OracleXmlType implements UserType, Serializable { 

 private static final long serialVersionUID = 2308230823023L; 

 private static final Class returnedClass = Document.class; 

 private static final int[] SQL_TYPES = new int[]{2007}; 

 private static final Logger LOG = LoggerFactory.getLogger(OracleXmlType.class); 

 public OracleXmlType() { 

 public int[] sqlTypes() { 

 return SQL_TYPES; 

 public Class returnedClass() { 

 return returnedClass; 

 public int hashCode(Object _obj) { 

 return _obj.hashCode(); 

 public Object assemble(Serializable _cached, Object _owner) throws HibernateException { 

 try { 

 return stringToDom((String)_cached); 

 } catch (Exception var4) { 

 throw new HibernateException("Could not assemble String to Document", var4); 

 public Serializable disassemble(Object _obj) throws HibernateException { 

 try { 

 return domToString((Document)_obj); 

 } catch (Exception var3) { 

 throw new HibernateException("Could not disassemble Document to Serializable", var3); 

 public Object replace(Object _orig, Object _tar, Object _owner) { 

 return this.deepCopy(_orig); 

 public boolean equals(Object arg0, Object arg1) throws HibernateException { 

 if (arg0 == null arg1 == null) { 

 return true; 

 } else { 

 return arg0 == null arg1 != null ? false : arg0.equals(arg1); 

 public Object deepCopy(Object value) throws HibernateException { 

 return value == null ? null : (Document)((Document)value).cloneNode(true); 

 public boolean isMutable() { 

 return false; 

 protected static String domToString(Document _document) throws TransformerException { 

 TransformerFactory tFactory = TransformerFactory.newInstance(); 

 Transformer transformer = tFactory.newTransformer(); 

 transformer.setOutputProperty("indent", "yes"); 

 if (_document == null) { 

 return " root /root 

 } else { 

 DOMSource source = new DOMSource(_document); 

 StringWriter sw = new StringWriter(); 

 StreamResult result = new StreamResult(sw); 

 transformer.transform(source, result); 

 return sw.toString(); 

 protected static Document stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException { 

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 

 DocumentBuilder builder = factory.newDocumentBuilder(); 

 if (StringUtils.isBlank(xmlSource)) { 

 xmlSource = " root /root 

 return builder.parse(new ByteArrayInputStream(xmlSource.getBytes("UTF-8"))); 

 public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor arg2, Object arg3) throws HibernateException, SQLException { 

 XMLType xmlType = null; 

 try { 

 xmlType = (XMLType)rs.getObject(names[0]); 

 } catch (Exception var7) { 

 LOG.error("Hibernate get XMLType Data Error!", var7); 

 return xmlType != null ? xmlType.getDOM() : null; 

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

 OracleNativeExtractor extrator = new OracleNativeExtractor(); 

 Connection nativeConn = extrator.getNativeConnection(st.getConnection()); 

 try { 

 XMLType xmlType = null; 

 if (value != null) { 

 xmlType = new XMLType(nativeConn, domToString((Document)value)); 

 st.setObject(index, xmlType); 

 } catch (Exception var8) { 

 throw new SQLException("Could not covert Document to String for storage"); 

Hibernate5项目

DatDocument.java

package com.jake.hib5.pojo; 

import lombok.Data; 

import org.hibernate.annotations.Type; 

import org.w3c.dom.Document; 

import javax.persistence.Column; 

import javax.persistence.Entity; 

import javax.persistence.Id; 

import javax.persistence.Table; 

@Data 

@Entity 

@Table(name = "DAT_DOCUMENT") 

public class DatDocument { 

 @Id 

 @Column(name = "APP_ID", unique = true, nullable = false, length = 100) 

 private String datDocumentId; 

 @Type(type = "com.jake.hib5.type.OracleXmlType") 

 @Column(name = "DOCUMENT_DATA", columnDefinition = "XMLTYPE") 

 private Document document; 

OracleXmlType.java

package com.jake.hib5.type; 

import java.io.ByteArrayInputStream; 

import java.io.IOException; 

import java.io.Serializable; 

import java.io.StringWriter; 

import java.sql.Connection; 

import java.sql.PreparedStatement; 

import java.sql.ResultSet; 

import java.sql.SQLException; 

import javax.xml.parsers.DocumentBuilder; 

import javax.xml.parsers.DocumentBuilderFactory; 

import javax.xml.parsers.ParserConfigurationException; 

import javax.xml.transform.Transformer; 

import javax.xml.transform.TransformerException; 

import javax.xml.transform.TransformerFactory; 

import javax.xml.transform.dom.DOMSource; 

import javax.xml.transform.stream.StreamResult; 

import com.gzsolartech.smartforms.hiextype.OracleNativeExtractor; 

import oracle.xdb.XMLType; 

import org.apache.commons.lang3.StringUtils; 

import org.hibernate.HibernateException; 

import org.hibernate.engine.spi.SharedSessionContractImplementor; 

import org.hibernate.usertype.UserType; 

import org.slf4j.Logger; 

import org.slf4j.LoggerFactory; 

import org.w3c.dom.Document; 

import org.xml.sax.SAXException; 

 * [email protected] 

 * [email protected],但该类实现的UserType接口来自Hibernate4, 

 * 其nullSafeGet和nullSafeSet方法的第三个参数与Hibernate5不同:Hibernate4为SessionImplementor, 

 * Hibernate5为SharedSessionContractImplementor,Postman访问时会报AbstractMethodError:nullSafeGet/nullSafeSet。 

 * 所以,解决方法就是重写OracleXmlType类,实现Hibernate5的UserType接口。 

public class OracleXmlType implements UserType, Serializable { 

 private static final long serialVersionUID = 2308230823023L; 

 private static final Class returnedClass = Document.class; 

 private static final int[] SQL_TYPES = new int[]{2007}; 

 private static final Logger LOG = LoggerFactory.getLogger(OracleXmlType.class); 

 public int[] sqlTypes() { 

 return SQL_TYPES; 

 public Class returnedClass() { 

 return returnedClass; 

 public int hashCode(Object _obj) { 

 return _obj.hashCode(); 

 public Object assemble(Serializable _cached, Object _owner) throws HibernateException { 

 try { 

 return stringToDom((String)_cached); 

 } catch (Exception var4) { 

 throw new HibernateException("Could not assemble String to Document", var4); 

 public Serializable disassemble(Object _obj) throws HibernateException { 

 try { 

 return domToString((Document)_obj); 

 } catch (Exception var3) { 

 throw new HibernateException("Could not disassemble Document to Serializable", var3); 

 public Object replace(Object _orig, Object _tar, Object _owner) { 

 return this.deepCopy(_orig); 

 public boolean equals(Object arg0, Object arg1) throws HibernateException { 

 if (arg0 == null arg1 == null) { 

 return true; 

 } else { 

 return arg0 == null arg1 != null ? false : arg0.equals(arg1); 

 public Object deepCopy(Object value) throws HibernateException { 

 return value == null ? null : (Document)((Document)value).cloneNode(true); 

 public boolean isMutable() { 

 return false; 

 protected static String domToString(Document _document) throws TransformerException { 

 TransformerFactory tFactory = TransformerFactory.newInstance(); 

 Transformer transformer = tFactory.newTransformer(); 

 transformer.setOutputProperty("indent", "yes"); 

 if (_document == null) { 

 return " root /root 

 } else { 

 DOMSource source = new DOMSource(_document); 

 StringWriter sw = new StringWriter(); 

 StreamResult result = new StreamResult(sw); 

 transformer.transform(source, result); 

 return sw.toString(); 

 protected static Document stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException { 

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 

 DocumentBuilder builder = factory.newDocumentBuilder(); 

 if (StringUtils.isBlank(xmlSource)) { 

 xmlSource = " root /root 

 return builder.parse(new ByteArrayInputStream(xmlSource.getBytes("UTF-8"))); 

 public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor arg2, Object arg3) throws HibernateException, SQLException { 

 XMLType xmlType = null; 

 try { 

 xmlType = (XMLType)rs.getObject(names[0]); 

 } catch (Exception var7) { 

 LOG.error("Hibernate get XMLType Data Error!", var7); 

 return xmlType != null ? xmlType.getDOM() : null; 

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

 OracleNativeExtractor extractor = new OracleNativeExtractor(); 

 Connection nativeConn = extractor.getNativeConnection(st.getConnection()); 

 try { 

 XMLType xmlType = null; 

 if (value != null) { 

 xmlType = new XMLType(nativeConn, domToString((Document)value)); 

 st.setObject(index, xmlType); 

 } catch (Exception var8) { 

 throw new SQLException("Could not covert Document to String for storage"); 

19598.html

cjavaoraclexml