#java #websphere
#java #websphere
Вопрос:
Я работаю с JPA, и у меня есть таблица, которая повторяется в n scheme. Запрос написан с использованием jpql, и мне нужно указать другую схему, основанную на необходимости избежать создания дублирующего кода. Точнее, я хочу изменить значение nameOfSchema аннотации @Table (name = "nameofTable", schema = "nameofSchema")
во время выполнения, а затем выполнить запрос. В связи с этим я написал следующий метод. При запуске с обычным JRE 1.7 он работает правильно, но когда я запускаю метод с websphere JRE 1.7, я получаю ошибку времени выполнения.
`public void changeTableSchema(final String schema,Class<?> entityWithTable) throws Exception {
try {
final String ANNOTATIONS = "annotations";
Table anntotationToChange = entityWithTable.getAnnotation(Table.class);
final Table anntotationToChangeCopy = anntotationToChange;
anntotationToChange = new Table() {
@Override
public Class<? extends Annotation> annotationType() {
return anntotationToChangeCopy.annotationType();
}
@Override
public UniqueConstraint[] uniqueConstraints() {
return anntotationToChangeCopy.uniqueConstraints();
}
@Override
public String schema() {
return schema;
}
@Override
public String name() {
return anntotationToChangeCopy.name();
}
@Override
public String catalog() {
return anntotationToChangeCopy.catalog();
}
};
Field annotations = Class.class.getDeclaredField(ANNOTATIONS);
annotations.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> map = (Map<Class<? extends Annotation>, Annotation>) annotations
.get(entityWithTable.class);
map.put(Table.class, anntotationToChange);
} catch (Exception e) {
e.printStackTrace();
}
} `
Ошибка:
java.lang.Исключение NoSuchFieldException: аннотации
на java.lang.Class.getDeclaredFieldImpl (собственный метод)
на java.lang.Class.getDeclaredField(Class.java: 720)
в it.solarisistemi.awondo.be.web.Prova.changeTableSchema(Prova.java: 106)
в it.solarisistemi.awondo.be.web.Prova.main(Prova.java: 23)
Комментарии:
1. почему не использовать Table.class.getDeclaredField (АННОТАЦИИ), а Class?
Ответ №1:
Причина этой ошибки в том, что вы взламываете невидимое поле в реализации java.lang.Class
, а реализации классов Java могут отличаться в зависимости от разных дистрибутивов JDK (например, Oracle vs. IBM JDK против OpenJDK).
Что еще более важно, эти внутренние поля могут быть изменены или исчезнуть между версиями JDK одного и того же поставщика (например, от IBM JDK 7 до IBM JDK 8) без предварительного уведомления, поскольку они никогда не предназначались для публичного доступа.
Я бы рекомендовал одно из следующих решений вместо взлома значений аннотаций:
- настройте псевдоним таблицы на стороне базы данных
- повторно скомпилируйте необходимые классы приложений с новыми значениями для
@Table.name()
Комментарии:
1. Спасибо за ответ. В конце концов я решил использовать собственные запросы вместо jpql. Это кажется очень ограниченным. Приветствия