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?
CodePudding user response:
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.