2

Suppose that I have the following HQL:

String hql = "select e.aField from MyEntity as e";

If I want to refactor and change the name of the MyEntity's member variable aField to something else, I also have to change all occurrences in the whole code in Strings. If I forget to change one hql string the code breaks.

How can I avoid this from happening?

IAdapter
  • 62,595
  • 73
  • 179
  • 242
nimcap
  • 10,062
  • 15
  • 61
  • 69

5 Answers5

4

You can used NamedQueries - you put your HQL as value of annotation on any entity and they are compiled to SQL at start-up time. if you have any errors in hql you wont be able to start your WebApp.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
IAdapter
  • 62,595
  • 73
  • 179
  • 242
2

Use an IDE that's smart enough to know how to do it for you, like IntelliJ. If I rename a class or variable, IntelliJ finds every use and manages the change for me.

duffymo
  • 305,152
  • 44
  • 369
  • 561
1

I believe you are looking for the same thing I was looking for... and found!

I use custom Hibernate templates to generate my Java code. I just took a copy of theirs and started messing around. It sounds scarier than it is - trust me.

I added the following code to the PojoFields.ftl file:

// These static property values are being generated by the POJO templates (PojoFields.ftl)
<#foreach field in pojo.getAllPropertiesIterator()>
    <#if pojo.getMetaAttribAsBool(field, "gen-property", true)>    
       <#assign name = pojo.getPropertyName(field) type = pojo.getJavaTypeName(field, jdk5)>
    public static final String ${field.name}_propname = "${field.name}";    
       <#foreach column in field.getColumnIterator()>     
          <#if pojo.getJavaTypeName(field, jdk5) == "String">
    public static final int ${field.name}_len = ${column.getLength()?c}; 
             <#break>                 
          </#if>    
      </#foreach>     
   </#if>   
</#foreach>

For all properties, it generates a public final static String that has the property name.

For String properties, it generates a public final static int that has the field length.

public static final String  postalCode_propname         = "postalCode";
public static final int     postalCode_len              = 15;

As long as I always use these static variables and never hard-code their values, I will avoid having RunTime errors related to a database structure change.

Examples:

Criteria criteria = session.createCriteria(ClPost.class).add(
            Restrictions.ne(ClPost.postalCode_propname, "90210"));

String hql = "select e." + ClPost.postalCode_propname 
    + " from " + ClPost.class.getSimpleName() + " as e";
bigleftie
  • 453
  • 1
  • 6
  • 17
0

you cannot since they are only strings (hard to refactoring by definition)

dfa
  • 114,442
  • 31
  • 189
  • 228
0

Options: 1. Use Criteria instead of HQL 2. Use NHibernateToLinq 3. create an enum of all of your attributes for each class and use that in you HQL (concatenation required)

epitka
  • 17,275
  • 20
  • 88
  • 141
  • 1
    With criteria you also need to have the field names as strings. Restrictions.eq("fieldname", foo) - this has the same problem with refactoring. – davidsheldon Jun 09 '09 at 22:19