Skip to content
Advertisement

@IndexedEmbedded on class containing other @IndexedEmbedded fields

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:

enter image description here

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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement