Index multiple properties in the same field

Hi @yrodiere ,

I was using hibernatesearch 5 earlier and now i migrated to hibernate 6 , so everything is working fine , but the way _all was configured earlier in hibernate 5 , is now not allowed in 6 why ? please help this feature is required

@Entity(name = Country.TABLE_NAME)
@Indexed(index = “ind_country”)
public class Country {

public static final String TABLE_NAME = "tbl_country";

public static final String ID_COLUMN = "id";

private static final String NAME_COLUMN ="name";

private static final String A2_CODE_COLUMN ="a2_code";

@Id
@Column(name=ID_COLUMN, nullable = false,length = 63)
private String id;

@Column(name = NAME_COLUMN,  length = 63)
@FullTextField(name="name")
@FullTextField(name="ALL") - was working earlier using @Field 
private String name;

@Column(name = A2_CODE_COLUMN,  length = 2)
@FullTextField(name="a2_code")
@FullTextField(name="ALL")
private String a2Code;

iam getting below exception
- HSEARCH400520: Duplicate index field definition: ‘ALL’.
Index field names must be unique.
Look for two property mappings with the same field name,
or two indexed-embeddeds with prefixes that lead to conflicting index field names,
or two custom bridges declaring index fields with the same name.

Hibernate Search 6 pays more attention to the fields you declare, what their capabilities are (single-valued or multi-valued in particular) and whether there are duplicates or not. As a result, for now, it doesn’t allow two properties to declare a field with the same name (in your case, ALL). This might get solved (in a way) once we introduce the ability to apply “labels” to fields with different names (HSEARCH-3926).

In the meantime, the easiest way to to what you want is to introduce a transient getter that declares the ALL field and returns all the values you want to assign to that field:

public static final String TABLE_NAME = "tbl_country";

public static final String ID_COLUMN = "id";

private static final String NAME_COLUMN ="name";

private static final String A2_CODE_COLUMN ="a2_code";

@Id
@Column(name=ID_COLUMN, nullable = false,length = 63)
private String id;

@Column(name = NAME_COLUMN,  length = 63)
@FullTextField(name="name")
private String name;

@Column(name = A2_CODE_COLUMN,  length = 2)
@FullTextField(name="a2_code")
private String a2Code;

@javax.persistence.Transient
@FullTextField(name="ALL")
@IndexingDependency(derivedFrom = {
        @ObjectPath(@PropertyValue(propertyName = "name")),
        @ObjectPath(@PropertyValue(propertyName = "a2Code"))
})
public List<String> getAll() {
    return Arrays.asList(name, a2Code);
}

Alternatively, you should be able to achieve the same result (and more) using a type bridge, but that solution will be more complex.

1 Like

thankyu @yrodiere , the above code worked like a charm

Hi @yrodiere
The above code worked like a charm , actually I have one more scenario to implement
that is to detect at runtime , that whether the field is searchable or non searchable - searchable means elasticsearch willl have that field , and non searchable means i will not even add that field in vo class (table entity class), but that field will be there in db table - so whenever user tries to get the data via api , runtime detection will happen that newly added field is non searchable and it is also not mapped in entity , but only in table field is present , and get data api will run smoothly without any error

so in short for non searchable field addition - only in table no need to change in codebase
and for searchable field addition - change in table and also in codebase - that will be okay

I’m not sure I understand what you mean; there doesn’t seem to be a question in your post?
In any case, if you need help about this, please start a new topic, as this looks like a different problem.