Как избежать жестко закодированных имен полей в HQL, Hibernate?

Предположим, что у меня есть следующий HQL:

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

Если я хочу реорганизовать и изменить имя MyEntityчленская переменная aField на что-то еще, я также должен изменить все вхождения во всем коде в строках. Если я забуду изменить одну строку hql, код нарушается.

Как я могу избежать этого?

5 ответов

Вы можете использовать NamedQueries - вы помещаете свой HQL в качестве значения аннотации для любой сущности, и они компилируются в SQL во время запуска. Если у вас есть какие-либо ошибки в hql, вы не сможете запустить свое WebApp.

Используйте IDE, которая достаточно умна, чтобы знать, как сделать это для вас, например, IntelliJ. Если я переименую класс или переменную, IntelliJ находит каждое использование и управляет изменениями для меня.

Я считаю, что вы ищете то же самое, что я искал... и нашел!

Я использую пользовательские шаблоны Hibernate для генерации своего кода Java. Я просто взял их копию и начал бездельничать. Звучит страшнее, чем есть - поверь мне.

Я добавил следующий код в файл PojoFields.ftl:

// 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>

Для всех свойств генерируется общедоступная конечная статическая строка с именем свойства.

Для свойств String он генерирует общедоступную конечную статическую переменную int, которая имеет длину поля.

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

Пока я всегда использую эти статические переменные и никогда не кодирую их значения жестко, я буду избегать ошибок RunTime, связанных с изменением структуры базы данных.

Примеры:

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";

Варианты: 1. Используйте Критерии вместо HQL 2. Используйте NHibernateToLinq 3. Создайте перечисление всех ваших атрибутов для каждого класса и используйте это в своем HQL (требуется конкатенация)

Вы не можете, так как они являются только строками (трудно рефакторинг по определению)

Другие вопросы по тегам