-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Problem with UserType, ParameterizedType
PostPosted: Tue Jan 31, 2006 5:23 pm 
Newbie

Joined: Thu Jan 06, 2005 1:46 pm
Posts: 8
Hi,
i'm using Hibernate 3.1.2 and i'm having, not a little problem to understand how hibernate decide to do an INSERT + and UPDATE in a specific case.

The problem :
When performing a persist operation on a brand new object without any reference to any objects, hibernate try to make two statements, 1 INSERT and 1 UPDATE.

Test #0:
As is
Result: 1 INSERT, 1 UPDATE
Explanation:????????? I need to understand :-)

Test #1:
Remove the property
Result : Only 1 INSERT

Test #2:
Add not-null="true"
Result: 1 INSERT

Test #3:
Add update="false"
Result: 1 INSERT

Test #4:
Remove optimistic-lock="false"
Result: 1 INSERT, 2 UPDATE
Explanation: Hibernate update also my "Base Class" responsible of the version control


Below you can find a subset of the mapping

Code:
<joined-subclass
.....

<property name="actionRequest"
column="AR_SRV_ACT_REQ_ID"
optimistic-lock="false">   
  <type name="xxx.xxx.hibernate.AgileEnumerationUserType">
<param name="targetClass">xxx.xxx.enumeration.EnmServerAction
</param>
</type>
</property>

....
</joined-subclass>   




Code:
public class AgileEnumerationUserType implements UserType, ParameterizedType {
    private Class targetClass;
   
   private static final int[] SQL_TYPES = {Types.BIGINT};
   
   public int[] sqlTypes() {
      return SQL_TYPES;
   }
   
   public Class returnedClass() {
      return targetClass;
   }
   
   public boolean equals(Object x, Object y) throws HibernateException {
      if(x == null || y == null)
         return false;
      return x.equals(y);
   }
   
   public Object deepCopy(Object value) throws HibernateException {
      return value;
   }
   
   public boolean isMutable() {
      return false;
   }
   
   public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
      Integer key = new Integer(resultSet.getInt(names[0]));
      AgileEnumeration enumeration;
      try {
         enumeration = (AgileEnumeration) targetClass.newInstance();
         enumeration.setKey(key);
      } catch (InstantiationException e) {
         throw new HibernateException(e);
      } catch (IllegalAccessException e) {
         throw new HibernateException(e);
      }

      return resultSet.wasNull() ? null : enumeration;
   }

   public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
      if (value == null) {
         statement.setNull(index, Types.BIGINT);
      } else {
         statement.setInt(index,((AgileEnumeration)value).intValue());
      }
   }
   
   public int hashCode(Object arg0) throws HibernateException {
      return arg0.hashCode();
   }

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

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

   public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
      return arg0;
   }
   public void setParameterValues(Properties parameters) {
        if(parameters == null)
           throw new HibernateException(ExceptionMessages.HIBERNATE_PLEASE_PROVIDE_TARGET_CLASS_FOR_ENUMERATION);
        String targetClassName = parameters.getProperty("targetClass");
        if(targetClassName == null)
           throw new HibernateException(ExceptionMessages.HIBERNATE_PLEASE_PROVIDE_TARGET_CLASS_FOR_ENUMERATION);

        try {
            targetClass = Class.forName(targetClassName);
            if (!(AgileEnumeration.class.isAssignableFrom( targetClass ))) {
              throw new HibernateException(ExceptionMessages.HIBERNATE_NOT_AN_ENUMERATION + ":" + targetClass);
            }
        } catch (ClassNotFoundException e) {
           throw new HibernateException(ExceptionMessages.HIBERNATE_PLEASE_PROVIDE_TARGET_CLASS_FOR_ENUMERATION);
        }      
   }

}



Code:

public class AgileEnumeration {
   private Integer key;
   private static Map reservedKeys = new HashMap();

   public AgileEnumeration() {
      key = null;
   }
   
   public AgileEnumeration(Integer key) {
      this.key = key;
   }
   
   public AgileEnumeration(int i) {
      key = new Integer(i);
      if(reservedKeys.containsKey(key)) {
         throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_DUPLICATE_KEY +
               ":" +
               getClass() +
               ":" +
               i +
               " -> " + 
               reservedKeys.get(key).getClass() +
               ":" +
               reservedKeys.get(key).toString());
      }
      reservedKeys.put(key, this);
   }
   public byte byteValue() {
      return key.byteValue();
   }

   public int compareTo(Integer anotherInteger) {
      return key.compareTo(anotherInteger);
   }

   public int compareTo(Object o) {
      if(o == null)
         return -1;
      if(!(o instanceof AgileEnumeration))
         return -1;
      return key.compareTo(((AgileEnumeration)o).key);
   }

   public double doubleValue() {
      return key.doubleValue();
   }

   public boolean equals(Object obj) {
      if(obj != null && getClass().isAssignableFrom(obj.getClass())) {
         AgileEnumeration other = (AgileEnumeration)obj;
         if(key == null && other.key == null)
            return true;
         return key != null && key.equals(other.key);         
      }
      return false;
   }

   public int hashCode() {
      if(key == null)
         return 0;
      return key.hashCode();
   }
   
   public float floatValue() {
      return key.floatValue();
   }

   public int intValue() {
      return key.intValue();
   }

   public long longValue() {
      return key.longValue();
   }

   public short shortValue() {
      return key.shortValue();
   }

   /**
    * toString is overridden to display a user and developer friendly string
    * instead of the numeric value.  We could and need to read the mapping
    * from a file to permit internationalization.  As of now, the implementation
    * uses reflection to use the field name as string.
    *
    * TODO: we need to change this to use a properties file
    */
   public String toString() {
        Field fieldList[] = this.getClass().getDeclaredFields();
      for(int i = 0; i < fieldList.length; i++) {
         try {
            if(this.getClass().equals(fieldList[i].getType()) &&
                  fieldList[i].get(this) != null && fieldList[i].get(this).equals(this)) {
               return fieldList[i].getName();
            }
         } catch (IllegalArgumentException e) {
            throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_NO_SUCH_FIELD_VALUE, e);
         } catch (IllegalAccessException e) {
            throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_NO_SUCH_FIELD_VALUE, e);
         }
      }
      //throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_NO_SUCH_FIELD_VALUE);
      
      //possible if the field is not actually static such as in DuplicateKeyIsDetected test...
      return null;
   }

   public Integer getKey() {
      return key;
   }

   public void setKey(Integer key) {
      this.key = key;
   }
   
   /**
    * Get all possible values creates a Set (because unique values only) of all possible
    * constants exposed by this class. It filters other field by checking that the field instance
    * is of the same type as the Enumeration class where it is located
    *
    * @param enumerationClass The class we want to get a list from
    * @return All possible values of the constants contained in this class
    *
    * TODO: add extra conditions to make sure the constants selected are public final static
    */
   static public Set getPossibleValues(Class enumerationClass) {       
        Field fieldList[] = enumerationClass.getDeclaredFields();
      Set results = new HashSet();
      for(int i = 0; i < fieldList.length; i++) {
         if(fieldList[i].getType().equals(enumerationClass)) {
            try {
               results.add(fieldList[i].get(null));
            } catch (IllegalArgumentException e) {
               throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_COULD_NOT_GET_ALL_FIELD_VALUES, e);
            } catch (IllegalAccessException e) {
               throw new AgileRuntimeException(ExceptionMessages.ENUMERATION_COULD_NOT_GET_ALL_FIELD_VALUES, e);
            }
         }
      }
      return results;
   }



Code:

public class EnmServerAction extends AgileEnumeration {

   public static final int IDBASE = 3600;
    public static final EnmServerAction START = new EnmServerAction(IDBASE + 1);
    public static final EnmServerAction PAUSE  = new EnmServerAction(IDBASE + 2);
    public static final EnmServerAction STOP  = new EnmServerAction(IDBASE + 3);
   
    public EnmServerAction() {
      super();
   }
   
    private EnmServerAction(int persistentValue) {
       super(persistentValue);
    }
   
   public static Set getInstances() {
      return AgileEnumeration.getPossibleValues(EnmServerAction.class);
   }
}



Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.