Skip to content

Instantly share code, notes, and snippets.

@xenji
Created July 31, 2016 18:39
Show Gist options
  • Select an option

  • Save xenji/712beba8dc7c7c5433678d5701b6c465 to your computer and use it in GitHub Desktop.

Select an option

Save xenji/712beba8dc7c7c5433678d5701b6c465 to your computer and use it in GitHub Desktop.

Revisions

  1. Mario Mueller created this gist Jul 31, 2016.
    172 changes: 172 additions & 0 deletions URICustomType.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,172 @@
    package com.xenji.xm.model.hibernate;

    import org.hibernate.HibernateException;
    import org.hibernate.engine.spi.SessionImplementor;
    import org.hibernate.usertype.UserType;

    import java.io.Serializable;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;

    /**
    * @author mmueller
    * @since 2016-07-30 13:48.
    */
    public class URICustomType implements UserType {
    /**
    * Return the SQL type codes for the columns mapped by this type. The
    * codes are defined on <tt>java.sql.Types</tt>.
    *
    * @return int[] the typecodes
    *
    * @see Types
    */
    @Override
    public int[] sqlTypes() {
    return new int[] {Types.OTHER};
    }

    /**
    * The class returned by <tt>nullSafeGet()</tt>.
    *
    * @return Class
    */
    @Override
    public Class returnedClass() {
    return URI.class;
    }

    /**
    * Compare two instances of the class mapped by this type for persistence "equality".
    * Equality of the persistent state.
    *
    * @return boolean
    */
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
    return x.equals(y);
    }

    /**
    * Get a hashcode for the instance, consistent with persistence "equality"
    */
    @Override
    public int hashCode(Object x) throws HibernateException {
    return x.hashCode();
    }

    /**
    * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
    * should handle possibility of null values.
    *
    * @param rs a JDBC result set
    * @param names the column names
    * @param owner the containing entity @return Object
    */
    @Override
    public Object nullSafeGet(
    ResultSet rs, String[] names, SessionImplementor session, Object owner
    ) throws HibernateException, SQLException {
    try {
    return new URI(rs.getString(names[0]));
    }
    catch (URISyntaxException e) {
    throw new HibernateException(e);
    }
    }

    /**
    * Write an instance of the mapped class to a prepared statement. Implementors
    * should handle possibility of null values. A multi-column type should be written
    * to parameters starting from <tt>index</tt>.
    *
    * @param st a JDBC prepared statement
    * @param value the object to write
    * @param index statement parameter index
    */
    @Override
    public void nullSafeSet(
    PreparedStatement st, Object value, int index, SessionImplementor session
    ) throws HibernateException, SQLException {
    if(value == null) {
    st.setObject(index, null, Types.OTHER);
    } else {
    final URI theUri = (URI)value;
    st.setObject(index, theUri.toString(), Types.OTHER);
    }
    }

    /**
    * Return a deep copy of the persistent state, stopping at entities and at
    * collections. It is not necessary to copy immutable objects, or null
    * values, in which case it is safe to simply return the argument.
    *
    * @param value the object to be cloned, which may be null
    *
    * @return Object a copy
    */
    @Override
    public Object deepCopy(Object value) throws HibernateException {
    return value;
    }

    /**
    * Are objects of this type mutable?
    *
    * @return boolean
    */
    @Override
    public boolean isMutable() {
    return false;
    }

    /**
    * Transform the object into its cacheable representation. At the very least this
    * method should perform a deep copy if the type is mutable. That may not be enough
    * for some implementations, however; for example, associations must be cached as
    * identifier values. (optional operation)
    *
    * @param value the object to be cached
    *
    * @return a cachable representation of the object
    */
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
    return (Serializable) value;
    }

    /**
    * Reconstruct an object from the cacheable representation. At the very least this
    * method should perform a deep copy if the type is mutable. (optional operation)
    *
    * @param cached the object to be cached
    * @param owner the owner of the cached object
    *
    * @return a reconstructed object from the cachable representation
    */
    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
    return cached;
    }

    /**
    * During merge, replace the existing (target) value in the entity we are merging to
    * with a new (original) value from the detached entity we are merging. For immutable
    * objects, or null values, it is safe to simply return the first parameter. For
    * mutable objects, it is safe to return a copy of the first parameter. For objects
    * with component values, it might make sense to recursively replace component values.
    *
    * @param original the value from the detached entity being merged
    * @param target the value in the managed entity
    *
    * @return the value to be merged
    */
    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
    return original;
    }
    }