97 lines
3.7 KiB
Java
97 lines
3.7 KiB
Java
package com.ankurm.hibernatedemo.search;
|
|
|
|
import jakarta.persistence.Entity;
|
|
import jakarta.persistence.GeneratedValue;
|
|
import jakarta.persistence.GenerationType;
|
|
import jakarta.persistence.Id;
|
|
import jakarta.persistence.JoinColumn;
|
|
import jakarta.persistence.ManyToOne;
|
|
import org.hibernate.search.engine.backend.types.Sortable;
|
|
import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexingDependency;
|
|
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField;
|
|
|
|
/**
|
|
* Chapter 25's Hibernate Search entity, pinned to {@code hibernate-search-mapper-orm}
|
|
* {@code 8.4.0.Final} (see {@code pom.xml} for why -- verified against Maven Central, NOT the
|
|
* {@code 7.3.2.Final} this repo's blog post previously claimed).
|
|
*
|
|
* <p>{@code title} is {@code @FullTextField} (analyzed, tokenized, fuzzy-matchable),
|
|
* {@code genre} is {@code @KeywordField} (stored whole, for exact-match filtering, never
|
|
* tokenized), {@code releaseYear} is a plain {@code @GenericField} marked sortable, and
|
|
* {@code director} is {@code @IndexedEmbedded} so a search on the director's name matches the
|
|
* movie without {@code Director} itself needing to be {@code @Indexed}.
|
|
*
|
|
* <p>Docs: docs/25-hibernate-search.md.
|
|
*/
|
|
@Entity
|
|
@Indexed
|
|
public class Movie {
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
// No explicit analyzer name: the Lucene backend ships no predefined "english" analyzer out
|
|
// of the box (confirmed the hard way -- naming one here without registering it via a
|
|
// LuceneAnalysisConfigurer bean fails the whole application context at startup with
|
|
// HSEARCH000353 "Unknown analyzer"). Omitting the attribute uses Hibernate Search's own
|
|
// built-in default full-text analyzer, which is enough for this chapter's examples.
|
|
@FullTextField
|
|
private String title;
|
|
|
|
@KeywordField
|
|
private String genre;
|
|
|
|
@GenericField(sortable = Sortable.YES)
|
|
private int releaseYear;
|
|
|
|
// @IndexedEmbedded on a @ManyToOne with no inverse side fails bootstrap outright
|
|
// (HSEARCH700020: "Unable to find the inverse side of the association") -- Hibernate Search
|
|
// needs to know how to find every Movie that embeds a given Director so it can reindex them
|
|
// when that Director changes. Director has no @OneToMany back-reference in this repo's
|
|
// model, and reindexing-on-director-update isn't something this chapter's tests exercise, so
|
|
// @IndexingDependency(reindexOnUpdate = SHALLOW) opts out of that automatic reindexing
|
|
// instead of adding a back-reference this model doesn't otherwise need.
|
|
@ManyToOne
|
|
@JoinColumn(name = "director_id")
|
|
@IndexedEmbedded
|
|
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
|
|
private Director director;
|
|
|
|
protected Movie() {
|
|
// for Hibernate
|
|
}
|
|
|
|
public Movie(String title, String genre, int releaseYear, Director director) {
|
|
this.title = title;
|
|
this.genre = genre;
|
|
this.releaseYear = releaseYear;
|
|
this.director = director;
|
|
}
|
|
|
|
public Long getId() {
|
|
return id;
|
|
}
|
|
|
|
public String getTitle() {
|
|
return title;
|
|
}
|
|
|
|
public String getGenre() {
|
|
return genre;
|
|
}
|
|
|
|
public int getReleaseYear() {
|
|
return releaseYear;
|
|
}
|
|
|
|
public Director getDirector() {
|
|
return director;
|
|
}
|
|
}
|