11
\$\begingroup\$

I am trying to use HibernateCompositeUser type to handle i18n specific data in my application. I am trying to use the below approach.

I have a table named master table which contains all locale independent data, while I have created another table master_translation which contains all locale sensitive information. Master table contains a reference to the master_translation.

Here is the detailed table structure:

master
 ---ID
 ---master_translation
 ---Other locale independent fields.

master_translation
 ---ID
 ---language_id
 ---Other locale sensitive fields

Now I am using HibernateCompositeUser type to handle this internal process. Here is the mapping for master class:

<hibernate-mapping>
    <class name="Master"
        table="MASTER">
        <id name="uuid" type="java.lang.String">
            <column name="UUID" />
            <generator class="uuid" />
        </id>

        <property name="master_i18n" type="masteri18n">
           <column name="NAME"/>
           <column name="SHORTDESCRIPTION"/>
           <column name="LONGDESCRIPTION"/>
    </class>
</hibernate-mapping>

where type="masteri18n" is hibernate CompositeUserType.now.

When I am fetching the master content, it is correctly fetching the data based on the language and my Master class contains a reference to the Master_translation which holds locale specific data.

I am handling this case:

public Object nullSafeGet(ResultSet rs, String[] arg1,
        SessionImplementor arg2, Object arg3) throws HibernateException,
        SQLException {

    Master_i18n master_i18n=Master_i18n.getInstance();
    master_i18n=dao.getMaster_i18n(rs.getString(arg1[0]), "nl_NL");;

    //return Master_i18n.getName();
    return Master_i18n;
}

@Override
public void nullSafeSet(PreparedStatement ps, Object arg1, int index,
            SessionImplementor arg3) throws HibernateException, SQLException {

    if(arg1==null){
        ps.setNull(index, Hibernate.STRING.sqlType());
        //ps.setNull(index+1, Hibernate.STRING.sqlType());
        //ps.setNull(index+2, Hibernate.STRING.sqlType());set
    }
    else{
         Master_i18n des=(Master_i18n)arg1;
         des=dao.saveMaster_i18n(des);
         ps.setString(index, des.getUuid());
         ps.setString(index+1, des.getUuid());
         ps.setString(index+2, des.getUuid());
         ps.setString(index+3, des.getUuid());    
    }
}

Somehow I am not feeling confident about my approach. Am I implementing it correctly or not?

\$\endgroup\$
6
+100
\$\begingroup\$

I'm not too familiar with Hibernate, so just some generic notes:

  1. DBMSs usually have case-insensitive attribute names, so a lot of people use underscore to separate words in attribute and table names.

    <column name="SHORTDESCRIPTION"/>
    <column name="LONGDESCRIPTION"/>
    

    In the case above SHORT_DESCRIPTION and LONG_DESCRIPTION would be easier to read.

  2.     Master_i18n master_i18n=Master_i18n.getInstance();
        master_i18n=dao.getMaster_i18n(rs.getString(arg1[0]), "nl_NL");;
    

    Master_i18n.getInstance() call seems unnecessary, since on the next line the local variable is overwritten. The following is the same (and the first line might not be required at all):

    Master_i18n.getInstance();
    Master_i18n master_i18n=dao.getMaster_i18n(rs.getString(arg1[0]), "nl_NL");;
    
  3. <id name="uuid" type="java.lang.String">
    

    java.lang.String could be simply string here.

  4. public Object nullSafeGet(ResultSet rs, String[] arg1,
            SessionImplementor arg2, Object arg3) throws HibernateException,
            SQLException {
    
        Master_i18n master_i18n=Master_i18n.getInstance();
        master_i18n=dao.getMaster_i18n(rs.getString(arg1[0]), "nl_NL");;
    
        //return Master_i18n.getName();
        return Master_i18n;
    }
    

    I think currently it does not compile, since return Master_i18n is uppercased Master_i18n which seems a class, not a local variable.

  5. master_i18n=dao.getMaster_i18n(rs.getString(arg1[0]), "nl_NL");;
    

    nl_NL could be a parameter/constant. (Does every caller want to use this locale?) (One of the semicolons is unnecessary at the end of the line.)

  6. I'd use longer and more descriptive variable names than ps, rs, arg1, arg3. Longer names would make the code more readable since readers don't have to decode the abbreviations every time when they read the code and don't have to guess which abbreviation the author uses.

    (Clean Code by Robert C. Martin, Avoid Mental Mapping, p25)

  7. Master_i18n is rather an ugly class name. It does not follow the usual CamelCase naming convention.

  8. It also looks like a singleton which is rather an antipattern nowadays. They make testing harder and often hide dependencies which leads to spaghetti code which is really hard to work with.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I don't think that java.lang.String could be String. In all xml configurations I've seen, you need to specify the complete "path" to the class. I can't find a clear reference but I'll keep searching. \$\endgroup\$ – Marc-Andre Mar 19 '14 at 15:29
  • 1
    \$\begingroup\$ @Marc-Andre: Thanks for the correction, you're probably right and I'Ve mixed it up with <property id="string=. I'll try to check it tomorrow. \$\endgroup\$ – palacsint Mar 19 '14 at 19:21
  • 2
    \$\begingroup\$ @Marc-Andre: I've tried it, it works with lowercase string (Hibernate 3.5.5). (String throws an exception.) \$\endgroup\$ – palacsint Mar 20 '14 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.