-->
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.  [ 6 posts ] 
Author Message
 Post subject: Hbm2Java & custom UserType problem in Hibernate-3
PostPosted: Mon Jun 19, 2006 7:19 pm 
Newbie

Joined: Thu Jun 08, 2006 11:57 am
Posts: 7
I am in the process of migrating my project code base to Hibernate-3
and having quite trouble with the way hibernate-tool in Hibernate3
work's with the CustomUserType's defined. The version of hibernate
being used is 3.1.3 and hibernate-tools is 3.1.0.beta4

Working version (old):
In Hibernate2, on invocation of hbm2java the following property in my *.hbm.xml

<property column="LAST_MODIFIED" length="11" name="lastModified"
type="com.company.hibernate.usertypes.LastModifiedColumnType">
<meta attribute="use-in-tostring">true</meta>
<meta attribute="default-value">new java.util.Date()</meta>
</property>

gets converted to the following

/** nullable persistent field */
protected Date lastModified = new java.util.Date();

which was correct & all the interfaces with setters and getters were
written accordingly.

e.g: public void setLastModified(java.util.Date dt),
public Date getLastModified();


NOT WORKING VERSION:
In Hibernate-3, on invocation of the new hibernate-tool that wraps
hbm2java, the same snippet from *.hbm.xml results

protected LastModifiedColumnType lastModified = new java.util.Date();

and hence all the code base breaks on the compile step coz =>

found : com.company.hibernate.usertypes.LastModifiedColumnType
required: java.util.Date

I have several other custom type's and I am not sure how this can be
fixed so that I can reuse my custom type(s). Is this a hibernate-tool
(hbm2java) bug in 3.1.0.beta-4 or is there a right way to accomplish
the same as in HIbernate-2.

Hibernate version: 3.1.3
Hibernate Tools version: 3.1.0-beta4


Top
 Profile  
 
 Post subject: RE: Hbm2Java & custom UserType problem in Hibernate-3
PostPosted: Mon Jun 19, 2006 8:34 pm 
Newbie

Joined: Wed Jun 14, 2006 7:40 pm
Posts: 8
First I'd like to say that I've never used Hibernate 2 , only the hibernate 3 but the code that is been generated is just fine.

When you are declaring a property to be of some custom type - in this case
Quote:
com.company.hibernate.usertypes.LastModifiedColumnType


then the natural thing Hibernate to do is to present this property as
Quote:
com.company.hibernate.usertypes.LastModifiedColumnType
.

Now you have to have another class perhaps named as
Quote:
com.company.hibernate.usertypes.LastModifiedColumnTypeUserType

this class is reqiured to provide the custom persistent for
Quote:
com.company.hibernate.usertypes.LastModifiedColumn


So when Hibernate sees property of (your) type
Quote:
com.company.hibernate.usertypes.LastModifiedColumnType

then it will invoke
Quote:
com.company.hibernate.usertypes.LastModifiedColumnTypeUserType
methods for storing and retrival of the data.

so the default-value should be
Quote:
new com.company.hibernate.usertypes.LastModifiedColumnType()


and inside this default constructor you may initialize the inner date field to
Quote:
java.util.Date

I'm not quite sure about the implementation of this custom type so I'm gussing here.

Of course the generated code then will be

Quote:
protected LastModifiedColumnType lastModified = new LastModifiedColumnType();


Some other dependent codes that expect the lastModified to be
Quote:
java.util.Date

- you have two options here -
1) to change all client code that depends on this property as
Quote:
java.util.Date
object or
2) to make the
Quote:
LastModifiedColumnType

to extend the
Quote:
java.util.Date

class (I personally do not recomend this sort of patches but this of course depends on some other factors so it is really up to you what decision to make)


Top
 Profile  
 
 Post subject: issue : with option # 2
PostPosted: Tue Jun 20, 2006 12:07 pm 
Newbie

Joined: Thu Jun 08, 2006 11:57 am
Posts: 7
I went ahead and made the LastModifiedColumnType to extend the java.util.Date but I get these compile errors. I couldnt understood why LMCT is not being considered as Date object. This is how the LMCT looks like:
Code:
package com.company.hibernate.usertypes;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

/**
* This Hibernate UserType is intended to update the LastModified Date field on the database
* when the entity is saved.
**/
//public class LastModifiedColumnType extends java.util.Date implements UserType
// public class LastModifiedColumnType implements org.hibernate.usertype.ParameterizedType

public class LastModifiedColumnType extends Date implements UserType
{
    public Date LastModifiedColumnType() {
    }

  /*
   */
  public int[] sqlTypes()
  {
    return new int[]
    {Types.TIMESTAMP};
  }

  /*
   *
   */
  public Class returnedClass()
  {
    return Date.class;
  }

  /*
   *
   */
  public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
    throws HibernateException,
    SQLException
  {
    return rs.getTimestamp(names[0]);
  }

  /*
   *
   */
  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 void nullSafeSet(PreparedStatement st, Object value, int index)
    throws HibernateException,
    SQLException
  {
    //This creates a Calendar initialized to right now
    final Calendar calendar = Calendar.getInstance();
    //This will be accurate to the second
    Timestamp rightNow = new Timestamp(calendar.getTime().getTime());
    int millis = calendar.get(Calendar.MILLISECOND);
    rightNow.setNanos(millis * 10);
    st.setTimestamp(index, rightNow);
  }

  /*
   */
  public Object deepCopy(Object value)
    throws HibernateException
  {
    if (value instanceof Date)
    { //
      return new Timestamp(((Date) value).getTime());
    }
    return null;
  }

  public boolean isMutable()
  {
    return false;
  }

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

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

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

    public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
        return deepCopy(arg0);
    }
}


The mapping file snippet:
Code:
        <property column="LAST_MODIFIED" length="11" name="lastModified"
            type="com.company.hibernate.usertypes.LastModifiedColumnType">
            <meta attribute="use-in-tostring">true</meta>
            <meta attribute="default-value">new com.company.hibernate.usertypes.LastModifiedColumnType()</meta>
        </property>


Code generated from the mapping file snippet:
Code:
public class Taxonomy extends com.company.portal.taxonomy.AbstractTaxonomyItem implements java.io.Serializable {

    protected LastModifiedColumnType lastModified = new com.company.hibernate.usertypes.LastModifiedColumnType();

    public LastModifiedColumnType getLastModified() {
        return this.lastModified;
    }
   
    public void setLastModified(LastModifiedColumnType lastModified) {
        this.lastModified = lastModified;
    }
}


Error on compilation:
Code:
hibernate-migration/components/taxonomy/target/generated-src/hbm2java/com/company/portal/taxonomy/model/Taxonomy.java:[17,7] com.company.portal.taxonomy.model.Taxonomy is not abstract and does not override abstract method setLastModified(java.util.Date) in com.company.portal.taxonomy.TaxonomyItem

hibernate-migration/components/taxonomy/target/generated-src/hbm2java/com/company/portal/taxonomy/model/Taxonomy.java:[146,34] getLastModified() in com.company.portal.taxonomy.model.Taxonomy cannot implement getLastModified() in com.company.portal.taxonomy.TaxonomyItem; attempting to use incompatible return type
found   : com.company.hibernate.usertypes.LastModifiedColumnType
required: java.util.Date


AbstractTaxonomyItem class:
Code:
public abstract class AbstractTaxonomyItem
  implements TaxonomyItem, Visitable, Cloneable
{
  public AbstractTaxonomyItem()
  {
    super();
  }

  public boolean hasChanged(Date date)
  {
    return date.before(getLastModified());
  }
}


TaxonomyItem interface:
Code:
public interface TaxonomyItem extends Serializable

  public Date getLastModified(); 
  public void setLastModified(final Date date); 
  public boolean hasChanged(final Date date);
}


Since LMCT extends Date, I would expect the new setter and getter should work but for some reason the compiler doesnt like it. Any idea what might be going wrong.. you mentioned something about inner date field in constructor.. could u plz elaborate/show an example of that. Let me know if you need any further clarification. Thanks for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 21, 2006 3:21 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
kchobantonov - your answer is unfortunately very wrong ;)

Hibernate does not do any "weird" guessing.

The usertype only need to implement the usertype it should never implement/extend the actual type it is supporting persistence for.

The "trick" is simply to remember to include the usertype in the classapath for the tooling - otherwise we cannot load it.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 27, 2008 1:38 pm 
Newbie

Joined: Wed Feb 27, 2008 1:33 pm
Posts: 3
max wrote:
The "trick" is simply to remember to include the usertype in the classapath for the tooling - otherwise we cannot load it.


How do you do this with the hibernate3-maven-plugin (2.1-SNAPSHOT)? I did have the custom types within the src/java dir of the mapping-project - did not work. Then i put the custom types into a different project and imported this as a dependency - didn't work either. With an ant buildscript it does / did work, so i guess my mapping is correct. But making a clean build with maven ist certainly preferable than first have to run ant just to generate the sources for the hibernate mapping.

Regards,
Julian.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 28, 2008 4:54 am 
Newbie

Joined: Wed Feb 27, 2008 1:33 pm
Posts: 3
k, jftr. I did solve my problem by specifying a meta-property within my mapping-file:

<meta attribute="property-type">java.lang.String</meta>

this way it worked ... probably regardless of classpath issues.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.