Невозможно установить аннотацию SolrDocument в RUNTIME
Я использую Spring Data Solr, и у меня есть следующий класс модели документа Solr и у меня есть соответствующий SolrCrudRepository для этого класса
@SolrDocument(collection = "oldCollectionName")
public class TestDocument {
@Id
@Indexed(name = "id", type = "string")
private String id;
@Field(value = "name")
private String name;
@Field(value = "externalid")
private Integer externalId;
}
Я пытаюсь изменить аннотацию "@SolrDocument(collection = "oldCollectionName")" во время выполнения.
У меня есть служба, которая имеет следующий метод, чтобы найти все документы, используя хранилище и класс модели
public List<TestDocument> getDocumentsByName(String name){
String newSolrDocument = getModifiedSolrCollectionName();
alterAnnotationValue(TestDocument.class, SolrDocument.class, newSolrDocument);
SolrDocument solrDocument = TestDocument.class.getAnnotation(SolrDocument.class);
LOGGER.info("Dynamically set SolrDocument Annotaation: "+solrDocument.collection());
return testDocumentRepository.findByName(name);
}
Код для изменения аннотации выглядит следующим образом
public void alterAnnotationValue(Class<?> targetClass, Class<? extends Annotation> targetAnnotation, Annotation targetValue) {
try {
Method method = Class.class.getDeclaredMethod(ANNOTATION_METHOD, null);
method.setAccessible(true);
Object annotationData = method.invoke(targetClass);
Field annotations = annotationData.getClass().getDeclaredField(ANNOTATIONS);
annotations.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> map = (Map<Class<? extends Annotation>, Annotation>) annotations.get(annotationData);
map.put(targetAnnotation, targetValue);
} catch (Exception e) {
e.printStackTrace();
}
}
Используя это, я правильно получаю набор newDocumentName в карту аннотаций, но при вызове метода find testDocumentRepository для поиска документов. Старое название коллекции выбирается.
Должен ли я сделать что-то еще, чтобы это работало? или мне чего-то не хватает?
Для справки, я следовал следующему учебнику http://www.baeldung.com/java-reflection-change-annotation-params
1 ответ
Почему бы вам просто не написать обычай SolrRepository
решить это? Вы можете ввести SolrTemplate
в вашем пользовательском репозитории, позволяя вам указать коллекцию для вашего запроса следующим образом:
public class TestDocumentRepositoryImpl implements TestDocumentRepository {
private SolrOperations solrTemplate;
...
public CustomSolrRepositoryImpl(SolrOperations solrTemplate) {
super();
this.solrTemplate = solrTemplate;
}
@Override
public TestDocument findOneSpecifyingCollection(String collection, String id) {
return solrTemplate.getById(collection, id, TestDocument.class);
}
}
Вы можете сделать это аналогично для нужной вам операции с хранилищем. Люди обычно нуждаются в своих собственных реализациях, если стандартные репозитории Spring JPA не удовлетворяют их потребностям. Тем не менее, вы все еще можете смешать свои со стандартными SolrCrudRepository
если это желательно.
Смотрите это для примера из весны.