Search Enums as String

Hi iam struggling to generate a generic search which for an Enum.

I want to search the Enum as String

@Enumerated
@KeywordField(
   sortable = Sortable.YES
)
private MyEnum myEnum;

e.g. like this (in my application the field name is a variable or is fields with an array of name)

session.search(scope).where(f -> f.match().field("myEnum").matching("enumName",ValueConvert.YES).fetch(10)

this could be solved by setting ValueConvert.NO but actually i dont’t want to use this always.
So I tried an own ValueBridge:

public class EnumAsString implements ValueBridge<Enum, String> {

  @Override
  public String toIndexedValue(Enum value, ValueBridgeToIndexedValueContext context) {
    return value == null ? null : value.toString();
  }
}

but when using this

org.hibernate.search.util.common.SearchException: HSEARCH000601: Inconsistent configuration for field 'myEnum' in a search query across multiple indexes: HSEARCH000603: Attribute 'dslConverter' differs:
'DslConverter[valueType=java.lang.Enum,delegate=PojoValueBridgeDocumentValueConverter[...util.valuebridges.EnumAsString@2a7f0dd6]]' vs.
'DslConverter[valueType=java.lang.Enum,delegate=PojoValueBridgeDocumentValueConverter[...util.valuebridges.EnumAsString@303235c7]]'.

Is there any idea to solve this in a clean way?

Hey,

I’m not quite sure what you are trying to achieve precisely…
From the error message you’ve provided, I could’ve suggested looking at the ValueBridge#isCompatibleWith(ValueBridge) if the indexes combined in the scope are actually compatible…

But if you are trying to search against multiple indexes at the same time and those are using different enums, and you want them to “look the same”, then maybe try something like this instead:

@Enumerated
private MyEnum myEnum; // no @KeywordField

@KeywordField(sortable = Sortable.YES) // create a derived property which will be a string 
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myEnum"))) // tell Hibernate Search what this field is derived from so that indexing works correctly 
public String getMyEnumString() {
	return myEnum == null ? null : myEnum.name();
}

This way, the field will be a string from the beginning, and no value conversion will be needed…

1 Like