バッチでデータのインデックスを作成しているときに問題が発生しました。情報を取得する必要があるメンバーArticle
を含むリストにインデックスを付けたいと考えています。他の 2 つの Bean から追加情報を取得します:と.@IndexedEmbedded
Article
Page
Articlefulltext
バッチはデータベースを正しくDocument
更新し、 Hibernate Search Annotations のおかげで Lucene インデックスに新しいものを追加します。しかし、追加されたドキュメントには不完全なフィールドがあります。Hibernate Search がすべての注釈を認識していないようです。
そのため、Luke のおかげで結果の lucene インデックスを見ると、Article オブジェクトと Page オブジェクトの両方に関するフィールドがいくつかありますが、ArticleFulltext に関するフィールドはありませんが、データベースに正しいデータがあります。これは、persist() 操作が正しく行われていることを意味します。 ..
自分のページと ArticleFullText の違いがわからないので、ここで本当に助けが必要です...
奇妙なことに、を使用するMassIndexer
と、Article + Page + Articlefulltext データが lucene インデックスに正しく追加されます。しかし、大きな更新を行うたびに何百万ものドキュメント インデックスを再構築したくありません...
Hibernate Search と lucene の log4j ロギング レベルを debug に設定しました。彼らは私に多くの情報を与えません。
これが私のBeanコードとバッチコードです。
よろしくお願いいたします。
Article.java :
@Entity
@Table(name = "article", catalog = "test")
@Indexed(index="articleText")
@Analyzer(impl = FrenchAnalyzer.class)
public class Article implements java.io.Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@DocumentId
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "firstpageid", nullable = false)
@IndexedEmbedded
private Page page;
@Column(name = "heading", length = 300)
@Field(name= "title", index = Index.YES, store = Store.YES)
@Boost(2.5f)
private String heading;
@Column(name = "subheading", length = 300)
private String subheading;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "article")
@IndexedEmbedded
private Articlefulltext articlefulltext;
[... bean methods etc ...]
Page.java
@Entity
@Table(name = "page", catalog = "test")
public class Page implements java.io.Serializable {
private Integer id;
@IndexedEmbedded
private Issue issue;
@ContainedIn
private Set<Article> articles = new HashSet<Article>(0);
[... bean method ...]
Articlefulltext.java
@Entity
@Table(name = "articlefulltext", catalog = "test")
@Analyzer(impl = FrenchAnalyzer.class)
public class Articlefulltext implements java.io.Serializable {
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "article"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "aid", unique = true, nullable = false)
private int aid;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@ContainedIn
private Article article;
@Column(name = "fulltextcontents", nullable = false)
@Field(store=Store.YES, index=Index.YES, analyzer = @Analyzer(impl = FrenchAnalyzer.class), bridge= @FieldBridge(impl = FulltextSplitBridge.class))
// This Field is not add to the Resulting Document ! I put a log into FulltextSplitBridge, and it's never called during a batch process. But if I use a MassIndexer, i see that FulltextSplitBridge is called for each Articlefulltext ...
private String fulltextcontents;
[... bean method ...]
データベースと Lucene インデックスの両方を更新するために使用されるコードは次のとおりです。
バッチソースコード:
FullTextEntityManager em = null;
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
ApplicationContext ap = null;
EntityManagerFactory emf = null;
EntityTransaction tx = null;
try {
ap = (ApplicationContext) arg0.getScheduler().getContext().get("applicationContext");
emf = (EntityManagerFactory) ap.getBean("entityManagerFactory", EntityManagerFactory.class);
em = Search.getFullTextEntityManager(emf.createEntityManager());
tx = em.getTransaction();
tx.begin();
// [... em.persist() some things which aren't lucene related, so i skip them ....]
for(File xmlFile : xmlList){
Reel reel = new Reel(title, reelpath);
em.persist(reel);
Article article = new Article();
// [... set Article fields, so i skip them ....]
Articlefulltext ft = new Articlefulltext();
// [... set Articlefulltext fields, so i skip them ....]
ft.setArticle(article);
ft.setFulltextcontents(bufferBlock.toString());
em.persist(ft); // i persist ft before article because of FK issues
em.persist(article); // there, the Annotation update Lucene index, but there's not updating fultextContent (see my first post)
if ( nbFileDone % 50 == 0 ) {
//flush a batch of inserts and release memory:
em.flush();
em.clear();
}
}
tx.commit();
}
catch(Exception e){
tx.rollback();
}
em.close();
}