javahibernatehibernate3

Hibernate 3 - safe to reuse IntegerType/StringType etc. objects?


I have some code/application which uses Hibernate 3.

It does calls like:
query.setParameter("MRC", getPageName(), new StringType());
query.setParameter("MBID", getMBID(), new IntegerType());

I want to replace these calls with some code like:
query.setParameter("MRC", getPageName(), STRING_TYPE);
query.setParameter("MBID", getMBID(), INTEGER_TYPE);

so that I don't have to instantiate these objects (the 3rd parameters) each time.

Here STRING_TYPE and INTEGER_TYPE will be static private class variables of types StringType and IntegerType respectively.

I wonder if that's safe to do (e.g. from multi-threading perspective, or purely from object reuse perspective).

I noticed that in later versions of Hibernate they imposed using the 2nd way of coding, but I am not sure if it's safe to follow this newer pattern in Hibernate 3 too.

Any ideas?


Solution

  • The StringType has <edited>no</edited> member fields and therefore no state itself. In the source code, all operations are either performed directly on the parameters or deal with singleton objects. That means that reusing a singleton instance is just as safe as creating a new instance each time. However, since the singleton instances are also immutable objects (a string constanct, String.class, or a static final int), then both variations should be considered safe.

    Here is the source code.

    package org.hibernate.type;
    
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;
    
    import org.hibernate.dialect.Dialect;
    
    /**
     * <tt>string</tt>: A type that maps an SQL VARCHAR to a Java String.
     * @author Gavin King
     */
    public class StringType extends ImmutableType implements DiscriminatorType {
    
        public Object get(ResultSet rs, String name) throws SQLException {
            return rs.getString(name);
        }
    
        public Class getReturnedClass() {
            return String.class;
        }
    
        public void set(PreparedStatement st, Object value, int index) throws     SQLException {
            st.setString(index, (String) value);
        }
    
        public int sqlType() {
            return Types.VARCHAR;
        }
    
        public String getName() { return "string"; }
    
        public String objectToSQLString(Object value, Dialect dialect) throws Exception {
            return '\'' + (String) value + '\'';
        }
    
        public Object stringToObject(String xml) throws Exception {
            return xml;
        }
    
        public String toString(Object value) {
            return (String) value;
        }
    
        public Object fromStringValue(String xml) {
            return xml;
        }
    
    }