Как избежать жестко закодированных имен полей в 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 (требуется конкатенация)
Вы не можете, так как они являются только строками (трудно рефакторинг по определению)