views:

1869

answers:

6

To validate data I am receiving I need to make sure that the length is not going to exceeded a database column length. Now all the length information is stored in the Hibernate mapping files, is there anyway to access this information programmatically?

A: 

Sorry I don't have an answer for this, but I noticed that this topic was brought up at the hibernate forums. Hope it helps

http://forum.hibernate.org/viewtopic.php?p=2404062

thorncp
Yeah I read that before I posted the question, they never arrive at a solution in the thread. Maybe this is something that is not supported in Hibernate, but it just seems so basic that I would find it absence to be a major omission in functionality.
James McMahon
+1  A: 

You can get to it but it's not easy. You might want to do something like below at startup and store a static cache of the values. There are a lot of special cases to deal with (inheritance, etc), but it should work for simple single-column mappings. I might have left out some instanceof and null checks.

for (Iterator iter=configuration.getClassMappings(); iter.hasNext();) {
    PersistentClass persistentClass = (PersistentClass)iter.next();
    for (Iterator iter2=persistentClass.getPropertyIterator(); iter2.hasNext();) {
       Property property = (Property)iter2.next();
       String class = persistentClass.getClassName();
       String attribute = property.getName();
       int length = ((Column)property.getColumnIterator().next()).getLength();
    }
  }
Brian Deterling
I will have to give this a try, thank you Brian.
James McMahon
A: 

Based on Brian's answer, this is what I ended up doing.

private static final Configuration configuration = new Configuration().configure();

public static int getColumnLength(String className, String propertyName) {
    PersistentClass persistentClass = configuration.getClassMapping(className);
    Property property = persistentClass.getProperty(propertyName);
    int length = ((Column) property.getColumnIterator().next()).getLength();

    return length;
}

This appears to be working well. Hope this is helpful to anyone who stumbles upon this question.

James McMahon
A: 

Sometimes it may be problem to get the Configuration object (if you are using some application framework and you are not creating session factory by yourself using the Configuration).

If you are using for example Spring, you can use the LocalSessionFactoryBean (from your applicationContext) to obtain Configuration object. Then obtaining of column length is just piece of cake ;)

factoryBean.getConfiguration().getClassMapping(String entityName) .getTable().getColumn(Column col).getLength()
stue
A: 

However, when I try to access the LocalSessionFactoryBean, I take a class cast exception

LocalSessionFactoryBean factoryBean = (LocalSessionFactoryBean) WebHelper.instance().getBean("sessionFactory");

exception: org.hibernate.impl.SessionFactoryImpl cannot be cast to org.springframework.orm.hibernate3.LocalSessionFactoryBean

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

This seems devious....

EDIT: found the answer. You need to use an ampersand in front of the bean name string LocalSessionFactoryBean factoryBean = (LocalSessionFactoryBean) WebHelper.instance().getBean("&sessionFactory");

see this Spring forum post

Gervase
A: 

I don't understand how using "&sessionFactory" works. Can anybody explain?

Mahendra