I am using Hibernate Search 3.4.2.
I have two class, Logs (the IndexEmbedded, OneToMany end), and LogFrame (the ContainedIn, ManyToOne end). The index (logFrames.content) does update properly when I do a session.save for the Logs class, but it doesn't update when I do a session.save on the LogFrame class even though I already have the ContaniedIn specified.
I need to be saving on the LogFrame end, because the LogFrames is expected to be a lot and I run into out of memory issues if I add all of them to the Logs.logFrame first before saving it.
This is the Logs.java
Code:
package com.test;
import static javax.persistence.GenerationType.IDENTITY;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
@Entity
@Table(name = "logs")
@Indexed
public class Logs {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "file_id", unique = true, nullable = false)
private Long fileId;
@Column(name = "USERNAME", unique = true, nullable = false, length = 10)
private String username;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "logs")
@IndexedEmbedded
private Set<LogFrame> logFrames = new HashSet<LogFrame>();
public Long getFileId() {
return this.fileId;
}
public void setFileId(Long fileId) {
this.fileId = fileId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Set<LogFrame> getLogFrames() {
return logFrames;
}
public void setLogFrames(Set<LogFrame> logFrames) {
this.logFrames = logFrames;
}
}
This is LogFrame.java
Code:
package com.test;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.ContainedIn;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
@Entity
@Table(name = "log_frame")
@Indexed
public class LogFrame {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Long id;
@Column(name = "content", nullable = false, length = 8000)
@Field(index = Index.TOKENIZED, store = Store.NO)
@Analyzer(impl = StandardAnalyzer.class)
private String content;
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinColumn(name = "file_id", referencedColumnName = "file_id", nullable = false)
@ContainedIn
private Logs logs;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Logs getLogs() {
return logs;
}
public void setLogs(Logs logs) {
this.logs = logs;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
This is the test program that writes the correct index
Code:
Session session = HibernateUtil.getSessionFactory()
.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
LogFrame frame;
Logs log;
log = new Logs();
log.setUsername("john");
frame = new LogFrame();
frame.setContent("Hello World 2");
log.getLogFrames().add(frame);
frame.setLogs(log);
session.save(log);
log = new Logs();
log.setUsername("jack");
session.save(log);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
And this one, which I am trying to get it work, doesn't write to the index properly.
Code:
Session session = HibernateUtil.getSessionFactory()
.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
LogFrame frame;
Logs log;
log = new Logs();
log.setUsername("john");
session.save(log);
frame = new LogFrame();
frame.setContent("Hello World 2");
frame.setLogs(log);
session.save(frame); // I am expecting this to update the index logFrames.content in the Logs index.
log = new Logs();
log.setUsername("jack");
session.save(log);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw e;
} finally {
session.close();
}
This is the code that I use for searching
Code:
Session session = HibernateUtil.getSessionFactory()
.openSession();
String searchQuery = "logFrames.content:Hello";
QueryParser parser = new QueryParser(Version.LUCENE_31,
"logFrames", new StandardAnalyzer(
Version.LUCENE_31));
org.apache.lucene.search.Query luceneQuery;
try {
luceneQuery = parser.parse(searchQuery);
} catch (ParseException e) {
throw new RuntimeException("Unable to parse query: "
+ searchQuery, e);
}
FullTextSession ftSession = Search.getFullTextSession(session);
org.hibernate.Query query = ftSession.createFullTextQuery(
luceneQuery, Logs.class);
List<Logs> results = query.list();
if (results.size() == 0) {
throw new RuntimeException("didn't get any results");
} else {
System.out.println("found!");
}
session.close();