当前位置: 首页 > 知识库问答 >
问题:

Hibernate搜索不索引/重新索引实体

惠野
2023-03-14
@Entity
@Indexed
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "userId")
    private Long id;
    (...)
    @Column(nullable = false, unique = true)
    @Field(index = Index.YES, analyze=Analyze.YES, store=Store.NO)
    private String email;
    (...)
    @Column(nullable = false, unique = true)
    @Field(index = Index.YES, analyze=Analyze.YES, store=Store.NO)
    private String username;
    (...)
}
@Repository
public class UserDAOImpl implements UserDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public long save(User toSave) {

        return (Long) this.sessionFactory.getCurrentSession().save(toSave);
    }
(...)
}
@Override
    public List<User> searchByEmail(String email) throws InterruptedException {

        return generateHibernateSearchQueryFor("email", email).list();
    }

    private org.hibernate.Query generateHibernateSearchQueryFor(String field, String searchParam) {

        FullTextSession fullTextSession = Search.getFullTextSession(sessionFactory.getCurrentSession());
        QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(User.class).get();

        org.apache.lucene.search.Query lQuery = queryBuilder.keyword().onFields(field).matching(searchParam).createQuery();
        org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(lQuery, User.class);

        return fullTextQuery;
    }
<bean id="hibernate4AnnotatedSessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="me.ksiazka.model" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>

                <prop key="hibernate.search.default.directory_provider">filesystem</prop>
                <prop key="hibernate.search.default.indexBase">src/searching_indexes</prop>
            </props>
        </property>
    </bean>
    @Test
    @DatabaseSetup("classpath:/testsDataset.xml")
    public void searchByEmailTest() {

        User u1 = new User("Maciej", "Adamowicz", "k2", "mac@gmial.com", "MacAda");
        userDAO.save(u1);

        List<User> u = null;
        try {
            //It worked at first - as new user was saved with hibernate he got his index in hibernate search indexes folder and searching found him.
            u = searchService.searchByEmail("mac@gmail.com");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //I know there should be asserts, its just for simplification for need of moment.
        System.out.println(":: " + u.size());
        System.out.println(":: " + u.get(0).getName());
    }


    List<User> u2 = null;
    try {
        //abc@gmial.com is in db - setted up by @DatabaseSetup
        u2 = searchService.searchByEmail("abc@gmail.com");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    //This didnt work, rows putted into db by dbunit doesn't have indexes in my indexing folder.
    System.out.println(":: " + u2.size());
    System.out.println(":: " + u2.get(0).getName());
}
@Before
    public void setupDatabase() {

        if(!doneBefore) {

            try {
                //It calls createIndexer().startAndWait() to make sure everything is indexed before test
                searchService.reindex();
            } catch (InterruptedException e) {    
                e.printStackTrace();
            }

            User u1 = new User("Maciej", "Adamowicz", "k2", "mac@gmial.com", "MacAda");
            userDAO.save(u1);

            doneBefore = true;
        }

    }
    @Test
    public void searchByEmailTest() {

        List<User> u = null;
        try {
            u = searchService.searchByEmail("mac@gmail.com");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Also asserts here, I know.
        System.out.println(":: " + u.size());
        System.out.println(":: " + u.get(0).getName());
    }

编辑:

在潜在的答案之后,我做了更多的测试。考虑到搜索有时会导致两倍或三倍的行,我尝试了.purgeall()并将索引提供程序更改为RAM,以确保在开始测试时索引是干净的。它没有根本改变。为了构建索引,我使用了.startandwait()。尝试用.index()“手工”构建它,但在尝试使用FullTextSession时遇到了一些嵌套事务问题。显式提交事务(或设置@rollback(false)-两者都尝试)也不起作用。我在Hibernate搜索文档链接中找到的所有东西。如果我在搜索之前用DAO保存一些东西,索引和搜索工作很好,但是在之前做同样的事情,然后搜索就不起作用了。

共有1个答案

涂承运
2023-03-14

当我记得正确的时候,Hibernate Search将在您提交事务时更新索引。

这对于普通代码没有问题,但在测试中,这种行为可能会导致问题,因为测试的一个常见模式是,在开始测试时启动事务,在测试结束时将事务返回,但从不提交它们。

要验证这是问题的原因,请创建一个测试,启动一个新的事务,修改某些内容,然后提交事务。然后在提交之后,检查hiberante搜索索引。

 类似资料:
  • 我使用< code > Hibernate Search 4 . 5 . 1 编写了< code>Spring web-app。当我尝试搜索时,它返回一个条目列表。我认为索引中的问题。用于索引的目录已创建,但实体保存文件后,目录中的文件不变。 这是我的Spring配置文件 我的实体文件

  • 我有大量相同类型的实体,每个实体都有大量属性,并且我只有以下两种选择来存储它们: 将每个项存储在索引中并执行多索引搜索 将所有enties存储在单个索引中,并且只搜索1个索引。 一般而言,我想要一个时间复杂度之间的比较搜索“N”实体与“M”特征在上述每一种情况!

  • 我编写了一个reindex方法,可以执行以下操作: 它确实起到了作用,但我现在确定,仅仅删除然后创建一个索引是否有意义。如何改进此方法?

  • bugu-mongo 2.x版本集成了Lucene的功能。当往MongoDB中新增一个Document时,能自动为该Document建立Lucene索引。相应的,当MongoDB中的Document被修改、删除时,对应的Lucene索引也会修改、删除。 另外,bugu-mongo还提供了对Lucene搜索的支持。根据Lucene索引进行搜索的时候,搜索结果能自动转换成对应的Entity对象。 在L

  • 我正在使用Hibernate Search/Lucene Intégration开发一个J2E应用程序。我索引文档(和其他实体),并希望对其进行不区分重音的搜索(内容和类的字段)。 这样做好吗?是否没有param或conf属性让FrenchAnalyzer忽略重音? 谢谢

  • 搜索引擎分为两部分: 时间筛选 和 搜索引擎 (详情) 1.时间筛选 便捷按钮有今日、昨日、前日、上周 X、近七天,并且能自定义选择时间段来得出想要的结果报表 2.搜索引擎 (时间段详情) 选择日期,查看来自对应时间段内,各个搜索引擎的访问量比例

  • 在测试此文本时,我在要在文本中搜索的列上创建了lucene(3.0.1)索引: 如果我按关键字搜索,它会给出结果,但按 我正在使用standardAnalyzer: 因为已设置,它应创建令牌,并且应存在$GLD。Analyzer将从文本中删除停止字,因为word也将在该过程中删除。

  • 主要内容:索引,下载索引,构件搜索我们知道,Maven 中央仓库为用户提供了多达数十万构件,而 Nexus 可以代理所有的远程仓库(包括 Maven 中央仓库),可见 Nexus 仓库中构件的数量相当庞大。用户想要在这么多构件中,快速的查找自己所需的构件,一个最直接有效的方式就是:搜索。 Nexus 作为一款成熟的仓库管理工具,它通过维护仓库的索引提供了构件搜索功能,以便帮助用户方便快速地找到所需构件。 本节我们将详细为您介绍 N