Кажется, вы используете (Hibernate Search)! Hibernate Search имеет вспомогательный класс, который может извлекать информацию о полях
FieldInfos fieldInfos = ReaderUtil.getMergedFieldInfos(indexReader);
К сожалению, FieldsInfos не содержит достаточно информации (обычно вы не знаете, хранится ли поле или нет: или, возможно, я что-то пропустил). Вот моя реализация, чтобы получить все сохраненные поля:
public class HBSearchHelper {
/**
* Get all fields of a entity which are stored into Lucene
*
* @param clazz
* @param prefix
* @return
*/
public static List<String> getStoredField(Class<?> clazz, String prefix) {
List<Field> fields = getAllFields(clazz);
ArrayList<String> storedList = new ArrayList<String>();
for (Field fi : fields) {
// @Field annotation
if (fi.isAnnotationPresent(org.hibernate.search.annotations.Field.class)) {
org.hibernate.search.annotations.Field annotation = fi.getAnnotation(org.hibernate.search.annotations.Field.class);
String storedName = getStoredFieldName(fi.getName(), annotation);
if (storedName != null) {
storedList.add(prefix + storedName);
}
}
// @Fields annotation (should contain one or more @Field annotations)
if (fi.isAnnotationPresent(org.hibernate.search.annotations.Fields.class)) {
org.hibernate.search.annotations.Fields annotation = fi.getAnnotation(org.hibernate.search.annotations.Fields.class);
org.hibernate.search.annotations.Field[] subAnnotations = annotation.value();
for (org.hibernate.search.annotations.Field subAnnotation : subAnnotations) {
String storedName = getStoredFieldName(fi.getName(), subAnnotation);
if (storedName != null) {
storedList.add(prefix + storedName);
}
}
}
// @IndexedEmbeded annotation
if (fi.isAnnotationPresent(org.hibernate.search.annotations.IndexedEmbedded.class)) {
org.hibernate.search.annotations.IndexedEmbedded annotation = fi.getAnnotation(org.hibernate.search.annotations.IndexedEmbedded.class);
String name = fi.getName();
// If the annotation has declared a prefix then use it instead of the field's name
if (annotation.prefix() != null && !annotation.prefix().isEmpty() && !annotation.prefix().equals(".")) {
name = annotation.prefix();
}
Class<?> embeddedClass = fi.getType();
if (Collection.class.isAssignableFrom(embeddedClass)) {
Type embeddedType = fi.getGenericType();
if (embeddedType instanceof ParameterizedType) {
Type[] argsType = ((ParameterizedType) embeddedType).getActualTypeArguments();
if (argsType != null && argsType.length > 0) {
embeddedClass = (Class<?>) argsType[0];
}
}
}
List<String> nestedFields = getStoredField(embeddedClass, prefix + name + ".");
if (nestedFields != null && !nestedFields.isEmpty()) {
storedList.addAll(nestedFields);
}
}
}
return storedList;
}
/**
* Returns the @Field's name if this @Field is stored otherwise returns null
*
* @param propertyName
* The name of the bean's property
* @param field
* The declared Hibernate Search annotation
* @return
*/
private static String getStoredFieldName(String propertyName, org.hibernate.search.annotations.Field annotation) {
Store store = annotation.store();
if (store == Store.YES || store == Store.COMPRESS) {
String name = propertyName;
// If the annotation has declared a name then use it instead of the property's name
if (annotation.name() != null && !annotation.name().isEmpty()) {
name = annotation.name();
}
return name;
}
return null;
}
/**
* Get all declared fields from the class and its super types
*
* @param type
* @return
*/
private static List<Field> getAllFields(Class<?> type) {
List<Field> fields = new ArrayList<Field>();
if (type != null) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
fields.addAll(getAllFields(type.getSuperclass()));
}
return fields;
}
}
Тогда довольно просто извлечь сохраненные поля сущности:
List<String> storedFields = HBSearchHelper.getStoredFields(MyEntity.class, "");
Должно работать на:
- сохраненные атрибуты (Stored.YES или Stored.COMPRESS)
- простые атрибуты (с указанным именем или без него)
- встроенные атрибуты (с префиксом или без него)
- объявление нескольких полей (т.е. аннотации @Fields)
Надеюсь, это кому-нибудь поможет.