I have a Dropwizard application which uses hibernate search. In a nutshell I have animals and their data in my database and I am trying to add a filter to get animals of a specific list of breeds. Unfortunately it seems that my filter doesn't work and I cant figure out why. I suspect it may be how I defined the relation between my entities and how I try to reference the breed attribute in the FilterFactory
, but it seems right to me. I have implemented my filter based on the Hibernate documentation. The relevant classes are as follows:
My Animal
class:
@Entity
@Indexed
@FullTextFilterDef(name = "animalFilter", impl = AnimalFilterFactory.class)
@Table(name = "animal")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Animal implements Serializable{
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@IndexedEmbedded
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "animal")
private AnimalInfo info;
// rest of the class goes here
}
My AnimalInfo
class:
@Entity
@Table(name = "animal_info")
@JsonIgnoreProperties(ignoreUnknown = true)
public class AnimalInfo implements Serializable{
@Id
@Column(name = "animal_id")
private Long animalId;
@IndexedEmbedded
@ManyToOne( cascade = CascadeType.ALL )
@JoinColumn(name="breed_id")
private AnimalBreed breed;
// rest of the class goes here
}
My AnimalBreed
class:
@Entity
@Table(name = "animal_breeds")
@JsonIgnoreProperties(ignoreUnknown = true)
public class AnimalBreed implements Serializable{
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* name of the breed which I want to filter my animals on.
*/
@Field
@Column(name = "name")
private String name;
And my filter class: Maybe the "info.breed.name"
statement is incorrect?
public class AnimalFilterFactory {
// list of breed names
private List<String> breeds;
public void setBreeds(List<String> breeds) {
this.breeds = breeds;
}
@Factory
public Query getFilter() {
BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
// apply filter for all the breeds
for (String breed : breeds) {
booleanQuery.add(new TermQuery( new Term( "info.breed.name", breed ) ), Occur.SHOULD);
}
return booleanQuery.build();
}
}
And in my DAO class where I want to apply the filter:
public List<Animal> getForBreeds(List<String> breedNames){
EntityManager em = this.currentSession();
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Animal.class)
.get();
qb.sort().byNative(SortField.FIELD_SCORE).andByNative(new SortField("id", Type.STRING, true));
org.apache.lucene.search.Query luceneQuery = qb.all().createQuery(); // get all the items
// apply filter
FullTextQuery ftq = fullTextEntityManager.createFullTextQuery(luceneQuery, Animal.class);
ftq.enableFullTextFilter("animalFilter").setParameter("breeds", breedNames);
return ftq.getResultList();
}
I have tested that, without applying the filter, all the Animal entities in my DB are returned. So it seems that the filter is definitely the issue.
Any help is appreciated.