I’m trying to manage hibernate search indexing on a class with a field mapped by @IndexedEmbedded on a custom @Embeddable entity. This entity also contains others @IndexedEmbedded fields in the @MappedSuperclass. These are the entities involved:
@Builder @Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString @Indexed @GeoPointBinding(fieldName = "location") public class Insertion { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "INSERTION_SEQ") private Long id; @NotNull @GenericField private Boolean publicated; @NotNull @Latitude private Double latitude; @NotNull @Longitude private Double longitude; @JsonIgnore private Point location; @FullTextField(analyzer = "generic_text") @KeywordField(name="city_sort", sortable = Sortable.YES, normalizer = "sort") private String city; @NotNull @Embedded @Valid @IndexedEmbedded private Amount amount; @IndexedEmbedded(name = "insertion_mate_preferences") @Embedded @Valid private MatePreference matePreferences; }
And these classes:
@SuperBuilder @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Embeddable public class MatePreference extends BaseProfile { @NotNull @GenericField private Integer minAge; @NotNull @GenericField private Integer maxAge; }
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @SuperBuilder @MappedSuperclass public abstract class BaseProfile implements BaseProfileView { @GenericField private Boolean smoker; @GenericField private Boolean children; @GenericField private Boolean hasAnimals; @GenericField private Boolean student; @GenericField private Boolean employed; @GenericField private String animalsDescription; @Enumerated(EnumType.STRING) @GenericField private Genre genre; @Enumerated(EnumType.STRING) @GenericField private OccupationSector occupation; @Enumerated(EnumType.STRING) @ElementCollection(fetch = FetchType.EAGER) @GenericField @IndexedEmbedded private Set<Personality> personalities; @Enumerated(EnumType.STRING) @ElementCollection(fetch = FetchType.EAGER) @GenericField @IndexedEmbedded private Set<Lifestyle> lifestyles; @ElementCollection(fetch = FetchType.EAGER) @GenericField @IndexedEmbedded private Set<Language> languages; @Enumerated(EnumType.STRING) @GenericField private StudyTitle titleOfStudy; @Enumerated(EnumType.STRING) @GenericField private StudyField studyField; }
When running the application, Hibernate Search throws the following error:
org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures: Hibernate ORM mapping: type 'it.friendshome.api.common.model.insertion.Insertion': path '.matePreferences<no value extractors>.languages': index 'Insertion': field 'insertion_mate_preferences': failures: - HSEARCH400520: Duplicate index field definition: 'languages'. 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. path '.matePreferences<no value extractors>.lifestyles': index 'Insertion': field 'insertion_mate_preferences': failures: - HSEARCH400520: Duplicate index field definition: 'lifestyles'. 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. path '.matePreferences<no value extractors>.personalities': index 'Insertion': field 'insertion_mate_preferences': failures: - HSEARCH400520: Duplicate index field definition: 'personalities'. 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. type 'it.friendshome.api.common.model.profile.Profile': path '.languages': index 'Profile': index schema root: failures: - HSEARCH400520: Duplicate index field definition: 'languages'. 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. path '.lifestyles': index 'Profile': index schema root: failures: - HSEARCH400520: Duplicate index field definition: 'lifestyles'. 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. path '.personalities': index 'Profile': index schema root: failures: - HSEARCH400520: Duplicate index field definition: 'personalities'. 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. type 'it.friendshome.api.common.model.search.Search': path '.matePreference<no value extractors>.languages': index 'Search': field 'matePreference': failures: - HSEARCH400520: Duplicate index field definition: 'languages'. 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. path '.matePreference<no value extractors>.lifestyles': index 'Search': field 'matePreference': failures: - HSEARCH400520: Duplicate index field definition: 'lifestyles'. 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. path '.matePreference<no value extractors>.personalities': index 'Search': field 'matePreference': failures: - HSEARCH400520: Duplicate index field definition: 'personalities'. 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.
I’m running it with the following dependencies:
Any suggestion on how to manage this scenario?
Advertisement
Answer
This code is incorrect:
@GenericField @IndexedEmbedded private Set<Language> languages;
With @GenericField
, you are asking Hibernate Search to generate a “value” field (string, integer, …) for languages. This generally won’t work, because Hibernate Search doesn’t know how to convert a Language
into a string/integer/…, so that’s a first problem.
But the second problem, and the one being reported by Hibernate Search, is that by also putting @IndexedEmbedded
on the same property, you are also asking Hibernate Search to generate an “object” (composite) field, with the same name as the “value” field from @GenericField
. So there’s a conflict: both the “value” field and the “object” field have the same name, “languages”.
You should remove @GenericField
wherever you use @IndexedEmbedded
.
Note that technically, you could use both @GenericField
and @IndexedEmbedded
on the same property, as long as you explicitly set a different name on either annotation using @GenericField(name = ...)
or @IndexedEmbedded(name = ...)
. But @GenericField
would not work unless you use a custom value bridge, and I don’t think your intention was to do that anyway. So please don’t do that unless you have an actual reason and @IndexedEmbedded
does not do what you want.