Hibernate XML Type

From PostgreSQL wiki
Revision as of 13:08, 5 August 2010 by Ringerc (talk | contribs) (New page: {{SnippetInfo|Java class to enable Hibernate to store and retrieve PostgreSQL XML fields|lang=Java|category=Library|depends=Nothing}} This Java class can be used to enable Hibernate to st...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Library Snippets

Java class to enable Hibernate to store and retrieve PostgreSQL XML fields

Works with PostgreSQL

Any version

Written in


Depends on


This Java class can be used to enable Hibernate to store and retrieve PostgreSQL "xml" typed fields as String objects. It's trivially adapted to parse the XML into a DOM and store from a DOM or whatever your preferred XML representation instead.

To tell Hibernate to use this UserType for a given mapped field, specify a Type annotation on the property, like:

private String markup;

If you're using Hibernate's XML mapping, add a "type" attribute to the "property" mapping, and specify the fully-qualified name of the type in the value. See, eg, this article.

Here's the source to the UserType. Feel free to adapt it as necessary. Be aware, though, that if you change the Java type in use to something that's mutable (ie where you can change the state of an instance) you must significantly adapt the implementation below according to the API documentation here.

Without using a UserType like this, you'll be able to retrieve xml columns fine, but on storing changes you'll receive a PostgreSQL error like:

ERROR:  column "markup" is of type xml but expression is of type character varying at character 122
package foo.bar;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;

 * Store and retrieve a PostgreSQL "xml" column as a Java string.
public class SQLXMLType implements org.hibernate.usertype.UserType {

    private final int[] sqlTypesSupported = new int[] { Types.VARCHAR };

    public int[] sqlTypes() {
        return sqlTypesSupported;

    public Class returnedClass() {
        return String.class;

    public boolean equals(Object x, Object y) throws HibernateException {
        if (x == null) {
            return y == null;
        } else {
            return x.equals(y);

    public int hashCode(Object x) throws HibernateException {
        return x == null ? null : x.hashCode();

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
        assert(names.length == 1);
        String xmldoc = rs.getString( names[0] );
        return rs.wasNull() ? null : xmldoc;

    public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        if (value == null) {
            st.setNull(index, Types.OTHER);
        } else {
            st.setObject(index, value, Types.OTHER);

    public Object deepCopy(Object value) throws HibernateException {
        if (value == null)
            return null;
        return new String( (String)value );

    public boolean isMutable() {
        return false;

    public Serializable disassemble(Object value) throws HibernateException {
        return (String) value;

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return (String) cached;

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;