Hibernate Search上的java.nio.channels.OverlappingFileLockException

时间:2017-11-29 07:35:14

标签: java postgresql hibernate lucene hibernate-search

我在我的项目中实现了非常基本的Hibernate Search。以下是搜索方法:

public List<Patients> search (String givenName, String middleName, String email, String phoneNumber) 
        throws InterruptedException, AppException {

    fullTextEntityManager = Search.getFullTextEntityManager(EntityManagerUtil.getEntityManager());          

    fullTextEntityManager.createIndexer().startAndWait();       

    QueryBuilder qb = fullTextEntityManager
            .getSearchFactory()
            .buildQueryBuilder()
            .forEntity(Patients.class)
            .overridesForField("givenName", "customanalyzer_query")
            .overridesForField("middleName", "customanalyzer_query")
            .overridesForField("email", "customanalyzer_query")
            .overridesForField("phoneNumber", "customanalyzer_query")
            .get();

    org.apache.lucene.search.Query luceneQuery = qb.bool()
                .must(qb.keyword().wildcard().onField("givenName").matching(givenName).createQuery())
                .must(qb.keyword().wildcard().onField("middleName").matching(middleName).createQuery())
                .must(qb.keyword().wildcard().onField("email").matching(email).createQuery())
                .must(qb.keyword().wildcard().onField("phoneNumber").matching(phoneNumber).createQuery()).createQuery();

    javax.persistence.Query jpaQuery =
            fullTextEntityManager.createFullTextQuery(luceneQuery, Patients.class);

    @SuppressWarnings("unchecked")
    List<Patients> result = jpaQuery.getResultList();

    return result;
}

我正在使用Postgresql来读取数据。

第一次运行时,一切都很顺利。索引将在目录中创建,搜索完成。

然后我继续在数据库中添加一些条目。添加后,我运行相同的搜索。有时我会得到所需的结果,有时它不会在搜索中包含新添加的条目。我得到了这个例外:

ERROR [Hibernate Search: Index updates queue processor for index com.healthelife.DGS.entity.Patients-1] (LuceneBackendQueueTask.java:73) - HSEARCH000073: Error in backend
java.nio.channels.OverlappingFileLockException
at sun.nio.ch.SharedFileLockTable.checkList(FileLockTable.java:255)
at sun.nio.ch.SharedFileLockTable.add(FileLockTable.java:152)
at sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1108)
at java.nio.channels.FileChannel.tryLock(FileChannel.java:1155)
at org.apache.lucene.store.NativeFSLock.obtain(NativeFSLockFactory.java:217)
at org.apache.lucene.store.Lock.obtain(Lock.java:72)
at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:1098)
at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.createNewIndexWriter(IndexWriterHolder.java:148)
at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.getIndexWriter(IndexWriterHolder.java:115)
at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriter(AbstractWorkspaceImpl.java:117)
at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.applyUpdates(LuceneBackendQueueTask.java:99)
at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.run(LuceneBackendQueueTask.java:67)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
ERROR [Hibernate Search: Index updates queue processor for index com.healthelife.DGS.entity.Patients-1] (LogErrorHandler.java:83) - HSEARCH000058: Exception occurred java.nio.channels.OverlappingFileLockException
Primary Failure:
Entity com.healthelife.DGS.entity.Patients  Id null  Work Type  org.hibernate.search.backend.PurgeAllLuceneWork

我的实体类:

@Produces(MediaType.APPLICATION_JSON)
@XmlRootElement
@AnalyzerDef(name = "customanalyzer_query", 
        tokenizer = @TokenizerDef(factory = WhitespaceTokenizerFactory.class),
        filters = {
            @TokenFilterDef(factory = LowerCaseFilterFactory.class),
            @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") 
        })

})
@Analyzer(definition = "customanalyzer_query")
public class Patients implements Serializable {

   private static final long serialVersionUID = -6061320465621019356L;

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "personId", nullable = false, unique = true)
   private Long personId;

   @Column(name = "prefix", nullable = true, unique = false)
   private String prefix;

   @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO, analyzer=@Analyzer(definition="customanalyzer_query"))
   @Column(name = "givenName", nullable = true, unique = false)
   private String givenName;

   @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO, analyzer=@Analyzer(definition="customanalyzer_query"))
   @Column(name = "middleName", nullable = true, unique = false)
   private String middleName;

   @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "gender", nullable = true)
   private Gender gender;

   @Column(name = "dateOfBirth", nullable = true, unique = false)
   private String dateOfBirth;

   @Column(name = "address1", nullable = true, unique = false)
   private String address1;

   @Column(name = "address2", nullable = true, unique = false)
   private String address2;

   @Column(name = "postalCode", nullable = true, unique = false)
   private String postalCode;

   @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO, analyzer=@Analyzer(definition="customanalyzer_query"))
   @Column(name = "phoneNumber", nullable = true, unique = false)
   private String phoneNumber;

   @Column(name = "phoneExt", nullable = true, unique = false)
   private String phoneExt;

   @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO, analyzer=@Analyzer(definition="customanalyzer_query"))
   @Column(name = "email", nullable = true, unique = false)
   private String email;        

   @Column(name = "city", nullable = true, unique = false)
   private String city; 

   @Column(name = "dateChanged", nullable = true, unique = false)
   private String dateChanged;

   @Column(name = "dateCreated", nullable = false, unique = false)
   private String dateCreated;

   @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
   @JoinColumn(name = "personIdentifiers", nullable = true)
   private PersonIdentifiers personIdentifiers;

   @Column(name = "profileImage", nullable = true, unique = false)
   private String profileImage;

   @Column(name = "nationality", nullable = true, unique = false)
   private String nationality;

   @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "visa", nullable = true)
   private VisaDetails visa;

   @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "emergencyContact", nullable = true)
   private EmergencyContact emergencyContact;

   @OneToMany(fetch = FetchType.EAGER, cascade= CascadeType.ALL)
   private List<IDProof> idproof = new ArrayList<>();

//getters and setters....
}

1 个答案:

答案 0 :(得分:0)

您需要确保对于用于存储Lucene索引的给定路径,您没有运行多个Hibernate Search实例。

这也意味着您必须确保任何Hibernate应用程序在关闭时正确停止;例如,需要关闭Hibernate SessionFactory:

sessionFactory.close();

当一个人仍在运行时,永远不要开始第二个副本:为了保护你不会犯这样的错误,锁定会抛出你所看到的异常。