-->
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.  [ 7 posts ] 
Author Message
 Post subject: Custom types to handle null primitive values
PostPosted: Fri Dec 15, 2006 6:14 am 
Beginner
Beginner

Joined: Fri Nov 24, 2006 10:33 am
Posts: 42
Hi

I'm converting an existing app from Spring JDBC to Hibernate.

Lots of our value objects have primitive member variables, which are nullable in the DB, which can cause Hibernate to throw an exception (when it tries to set a primitive to null).

I've got around it by modifying the value objects to hold e.g. Boolean values instead of boolean.

But, I know there's a way of using 'Custom Types' which will set the variable to a default value if it's null. I thought this would be a simple matter of adding an attribute e.g. type="boolean" to the column mapping, but the few variations I've tried haven't worked.

Does anyone know how I can use custom types, so I don't have to modify all my value objects please?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 7:11 am 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
I don't have much time to test it, though maybe you could test declaring something like :
Code:
<typedef name="int" class="com.yourcompany.YourUserType" />

Then implement a class that inherits UserType from Hibernate and see if you can control how int or others are processed.

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 7:19 am 
Beginner
Beginner

Joined: Fri Nov 24, 2006 10:33 am
Posts: 42
Thanks for the tip - I'll give it a go.

I was hoping to use the built-in NullableTypes defined in net.sf.hibernate.Hibernate

The way I tried didn't work, but then I was using "type=" rather than "class="

I'll try it now

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 7:52 am 
Beginner
Beginner

Joined: Fri Nov 24, 2006 10:33 am
Posts: 42
This is what we did - almost the same

type="com.lsb.uk.mqs.dao.hibernate.PrimitiveIntType"

The PrimitiveIntType has quite a bit of code in it though. I can't help thinking that Hibernate must provide implementations for all primitive types already though.

Surely this must be a common requirement for people (especially those upgrading existing systems)

Here's the code though

package com.lsb.uk.mqs.dao.hibernate;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

Code:
public class PrimitiveIntType implements UserType {

   private Integer defaultValue = new Integer(0);

   public int[] sqlTypes() {
      return new int[] { Types.INTEGER };
   }

   public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
      return arg0;
   }

   public Object deepCopy(Object arg0) throws HibernateException {
      return new Integer(((Integer) arg0).intValue());
   }

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

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

   public int hashCode(Object x) throws HibernateException {
      return x.hashCode();
   }

   public boolean isMutable() {
      return false;
   }

   public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
      Number result = (Number) rs.getObject(names[0]);
      return result == null ? defaultValue : new Integer(result.intValue());
   }

   public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
      if (value == null || defaultValue.equals(value)) {
         LogFactory.getLog(getClass()).trace("binding null to parameter: " + index);
         st.setNull(index, Types.INTEGER);
      } else {
         LogFactory.getLog(getClass()).trace("binding " + value + " to parameter: " + index);
         st.setInt(index, ((Integer) value).intValue());
      }

   }

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

   public Class returnedClass() {
      return int.class;
   }

}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 8:21 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
we tend to avoid having builtin support for mappings there are inconsistent/non-symmetrical.

Your use case is a typical scenario usertypes were intended for.

btw. using typedef can reduce your need for typing drastically ;)

<typedef name="nullint" class="com.lsb.uk.mqs.dao.hibernate.PrimitiveIntType">
<param name="defaultValue">0</param>
</typedef>

and then you just need to refer to nullint.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 9:49 am 
Beginner
Beginner

Joined: Fri Nov 24, 2006 10:33 am
Posts: 42
Thanks for that - works great.

One last question - can I declare the typedef globally, or do I have to include it in each mapping file that needs it?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 15, 2006 9:55 am 
Beginner
Beginner

Joined: Fri Nov 24, 2006 10:33 am
Posts: 42
Just realised, if you declare the TypeDef in the first mapping file that's listed in the sessionFactory's config, all the others will pick it up automatically

I should have checked that before my last post :)


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

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.