-->
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.  [ 8 posts ] 
Author Message
 Post subject: Automatically truncating string (varchar) fields
PostPosted: Thu Nov 13, 2003 1:31 am 
Newbie

Joined: Thu Aug 28, 2003 1:05 am
Posts: 4
Location: Australia
With M$SQLServer and the JSQLConnect driver (not sure about other db/driver combos) if a string property of an entity has been set with a value longer than the field in the database, it can not be saved.

Is there a way to be able to configure a string property to autotruncate when persisting and log a warning about the truncation, instead of failing completely?

I was thinking:
Code:
     * @hibernate.property
     *      length="200"
     *      truncate-to-fit="true"
     */
    public String getResponse()
    ...

Code:
<property
    name="response"
    type="java.lang.String"
    column="response"
    length="200"
    not-null="false"
    unique="false"
    truncate-to-fit="true"
/>


If needed on more extensive scale than per-column, maybe it could be specifed per class/table/session/sessionfactory.

Note: Unfortunately, for other reasons we are not able to use a TEXT type for this field (which would solve any truncation problems).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 13, 2003 9:35 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
You can do this with a UserType.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 13, 2003 8:33 pm 
Newbie

Joined: Thu Aug 28, 2003 1:05 am
Posts: 4
Location: Australia
That will be a nice solution, thanks.

I can create a TruncateStringType for every length that I need to truncate (ie: TruncateStringType50, TruncateStringType100, ...) but it would be better to have one TruncateStringType, that can use length field to determine what length to truncate.

Is there any way the UserType can access the meta-data of the property (most notably the length)?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 13, 2003 8:41 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Umm not currently. I'll give this some thought. Please submit a feature request to JIRA.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 13, 2003 10:27 pm 
Newbie

Joined: Thu Aug 28, 2003 1:05 am
Posts: 4
Location: Australia
Added as HB-469


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 13, 2003 11:22 pm 
Newbie

Joined: Thu Aug 28, 2003 1:05 am
Posts: 4
Location: Australia
In case anyone stubles accross this post with the same problem, my solution is:

Code:
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.hibernate.type.StringType;
import net.sf.hibernate.util.StringHelper;

/**
* @author MarcWilson
*/
public abstract class TruncateStringType extends StringType
{
    private static final Log log = LogFactory.getLog( StringHelper.qualifier( TruncateStringType.class.getName() ) );

    public static class TruncateStringType5    extends TruncateStringType {}
    public static class TruncateStringType50   extends TruncateStringType {}
    public static class TruncateStringType100  extends TruncateStringType {}
    public static class TruncateStringType200  extends TruncateStringType {}
   
    private int length;
   
    protected TruncateStringType()
    {
        this.length = getLength(getClass().getName());
    }
   
    private int getLength(String className)
    {
        int i = className.length();
        while(Character.isDigit(className.charAt(i-1)))
        {
            i--;
        }
        return Integer.parseInt(className.substring(i));
    }
   
    Object truncate(String value)
    {
        if(value != null && value.length() > length)
        {
            log.warn("String value of length " + value.length() + " was truncated to length " + length + " to fit");
            if(log.isDebugEnabled())
            {
                log.debug("Initial (untruncated) string:" + value);
            }
            value = value.substring(0, length);
        }
        return value;
    }

    public void set(PreparedStatement st, Object value, int index) throws SQLException
    {
        super.set(st, truncate((String)value), index);
    }
}


which can be used like:
Code:
<property
    name="response"
    type="TruncateStringType$TruncateStringType200"
    column="response"
    length="200"
    not-null="false"
    unique="false"
/>


I extended StringType instead of implementing UserType, but I think I have achieved the same objective (although leaving it opens to problems from future changes in the StringType implementation).

The annoying part is u need to add another TruncateStringTypeXXXX class for every new length (XXXX) you want to be able to truncate to. This can be fixed if and when HB-469 is implemented.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 14, 2003 3:02 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
It must be more usefull to decorate driver or fork and modify your favorite connection pool.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 22, 2005 12:16 pm 
Regular
Regular

Joined: Tue Sep 28, 2004 5:18 pm
Posts: 55
Location: Switzerland
So did this issue die out? I'd rather have the Derby DB truncate strings to fit than crash. A quick search of the forum turned up this issue, which seems to be in limbo since 2003? Any updates? A more current forum topic?


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