I am building an application with Hibernate Search 4.5.1 and Spring 4.0.5.RELEASE. I am trying to index the following class:
Code:
@Entity
@Indexed
@Analyzer(impl= org.apache.lucene.analysis.standard.StandardAnalyzer.class)
@Table(name="SONG")
@XmlRootElement(name="song")
public class Song
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", updatable = false, nullable = false)
private Long id;
@Field(store = Store.YES)
@Column(name="NAME", length=255)
private String name;
@Field(store = Store.YES)
@Column(name="ALBUM", length=255)
private String album;
@Field(store = Store.YES)
@Column(name="ARTIST", length=255)
private String artist;
@NotNull
@Column(name="PATH", length=255)
private String path;
@NotNull
@Column(name="PATH_COVER", length=255)
private String cover;
@NotNull
@Column(name="LAST_VOTE")
private Date date;
@Field(store = Store.YES)
@NotNull
@Column(name="N_VOTES")
private int nvotes;
@NotNull
@Column(name="ACTIVE", nullable=false, columnDefinition="TINYINT(1) default 0")
private boolean active;
@OneToOne(fetch=FetchType.LAZY)
@JoinColumn(name="IMAGE_ID",insertable=true,updatable=true,nullable=false,unique=false)
private Image image;
@IndexedEmbedded
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PLAYLIST_ID", nullable = false)
private PlayList playList;
@OneToMany(mappedBy = "song")
private Set<UserVotes> userServices = new HashSet<UserVotes>();
I am building a junit test case which looks like this:
Code:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:jukebox-servlet-test.xml"})
@Transactional
public class SongDaoTest {
@Autowired
public I_PlaceDao placeDao;
@Autowired
public I_PlayListDao playListDao;
@Autowired
public I_SongDao songDao;
@Before
public void prepare() throws Exception
{
Operation operation = sequenceOf(CommonOperations.DISABLE_CONTRAINTS, CommonOperations.DELETE_ALL,CommonOperations.INSERT_SONG_DATA, CommonOperations.ENABLE_CONTRAINTS);
DbSetup dbSetup = new DbSetup(new DriverManagerDestination("jdbc:mysql://localhost:3306/jukebox", "root", "mpsbart"), operation);
dbSetup.launch();
FullTextSession fullTextSession = Search.getFullTextSession(placeDao.getSession());
fullTextSession.createIndexer().startAndWait();
}
@Test
@Rollback(false)
public void searchTest()
{
PlayList playList = playListDao.read(1l);
List<Song> songs = songDao.search(playList, "offspring", 1, 10);
assertEquals(10, songs.size());
}
The search method implementation is:
Code:
@SuppressWarnings("unchecked")
public List<Song> search(PlayList playlist, String searchTerm,int page,int limit)
{
FullTextSession fullTextSession = Search.getFullTextSession(getSession());
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Song.class).get();
BooleanQuery luceneQuery = new BooleanQuery();
luceneQuery.add(queryBuilder.keyword().onFields("name","album","artist").matching("*"+searchTerm+"*").createQuery(), BooleanClause.Occur.MUST);
luceneQuery.add(queryBuilder.phrase().onField("playList.place.id").sentence("\""+playlist.getPlace().getId()+"\"").createQuery(), BooleanClause.Occur.MUST);
luceneQuery.add(queryBuilder.phrase().onField("playList.id").sentence("\""+playlist.getId()+"\"").createQuery(), BooleanClause.Occur.MUST);
// wrap Lucene query in a javax.persistence.Query
FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Song.class);
org.apache.lucene.search.Sort sort = new Sort(new SortField("n_votes",SortField.INT));
query.setSort(sort);
List<Song> songs = query.setFirstResult(page*limit).setMaxResults(limit).list();
return songs;
}
The test result fails, it does not find any matching object. When using luke lucene I can see that there are results, if I try the query generated by hibernate on luke it does return elements. The query generated by hibernate is: +(name:metallica album:metallica artist:metallica) +playList.place.id:"*1*" +playList.id:"1"
I have also noticed on luke lucene that some index terms have a length up to six characters, for an instance, one song's artist it's "The Offspring" and the terms stored in the index are "the" and "offspr". The first one it's ok, but shouldn't the second term be "offspring". Why is it truncating the name?