1

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?

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • 1
    Why don't you use setString(), setInteger(), etc. It would be simpler, cleaner, and safer. – JB Nizet Mar 15 '19 at 16:06
  • @JBNizet Because `setInteger` doesn't fit my needs, it does not allow me to pass the `Integer` `null` to the DB function which I am calling. It requires an `int`. – peter.petrov Mar 15 '19 at 16:32

2 Answers2

2

StringType has an INSTANCE-Field which contains an instance you can reuse. The Type-Classes map between Java and SQL-Types and have no state, so it's fine to reuse them.

Claus Radloff
  • 357
  • 1
  • 11
  • Can you back it up with some code? [Docs](https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/type/StringType.html) dont match [code on github](https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/type/StringType.java) – XtremeBaumer Mar 15 '19 at 16:08
  • @XtremeBaumer The next version of Hibernate, that you're looking at on Github, is 5.x.x. The documentation you linked to is 3.2. Many years have passed since 3.2, and many changes have been done. It went out in 2006, 13 years ago. – JB Nizet Mar 15 '19 at 16:12
  • Ups, the INSTANCE-Field was added later. But one can define a constant and reuse it. Multithreading isn't an issue also, because the class is stateless. – Claus Radloff Mar 15 '19 at 16:12
  • The constants exist in 3.6. One can only hope that the OP is at least using the latest 3.x version. – JB Nizet Mar 15 '19 at 16:13
  • By the way, Hibernate detects Strings and Integers itself, so there is no need to specify the type. Just use the setParameter-Method with two parameters. – Claus Radloff Mar 15 '19 at 16:15
  • @JBNizet i know that they are different versions. Thats why i asked for code from hibernate3 – XtremeBaumer Mar 15 '19 at 16:15
  • Of course the INSTANCE field was added later than in version 3. That's what my question is all about. The first thing I did was to look for this INSTANCE field (because in other projects/apps I use later versions of Hibernate which have that field). But Hibernate 3 does not have that field. And that's what raised my question. – peter.petrov Mar 15 '19 at 16:59
1

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;
    }

}
Nathan
  • 1,576
  • 8
  • 18