2

I'm using Hibernate Search and looking to index an object that has polymorphic relationships that use @Any and/or @ManyToAny.

@Indexed
public class Foo {
    @Any(metaDef="fooOwnerType", metaColumn=@Column(name="ownerType"))
    @JoinColumn(name="ownerId")
    @IndexedEmbedded // this DOES NOT WORK
    private OwnerType owner;

    @OneToOne
    @IndexedEmbedded // this WORKS
    private User user;

    @OneToOne
    @IndexedEmbedded // this WORKS
    private Company company;

    @Field
    private String description;
}

@Indexed
public class User implements OwnerType {
    @Field
    private String name;

    @Field
    private String address;
}

public class Company implements OwnerType {
    @Field
    private String name;
}    

public interface OwnerType {
}

I can search and find Foo objects using text in the description field without issue. What I'd also like to do is find Foo objects when User.name or User.address is matched... but Hibernate Search doesn't seem to index these fields for me due to the polymorphic relationship OwnerType owner.

It would work fine if I use @IndexedEmbedded on a concrete object (User or Company) directly as expected.

djmistral
  • 57
  • 5

1 Answers1

0

Yes, this is expected. @IndexedEmbedded only adds fields for the exposed type of the embedded field. There are no concrete plans to fix it at the moment, but there is a feature request here: https://hibernate.atlassian.net/browse/HSEARCH-438 Also, interfaces cannot be mapped for indexing, only classes can. This will be fixed in Search 6: https://hibernate.atlassian.net/browse/HSEARCH-1656

One way to make your code work would be to turn OwnerType into an abstract class, either a @MappedSuperclass or an @Entity, and move the fields that are common to every subclass there.

EDIT: If the user/company associations are mutually exclusive (only one can be non-null), another way to make it work would be to simply query both. For example instead of querying owner.name, query both fields user.name and company.name. The Hibernate Search DSL allows that: just use .onFields("user.name", "company.name") instead of .onField("owner.name").

yrodiere
  • 9,280
  • 1
  • 13
  • 35