ElasticSearchRepository deleteBy在单元测试中不起作用

问题描述 投票:0回答:1

我正在使用spring-data-elasticsearch和spring-data-jest将数据通过spring-boot应用程序存储在elasticsearch中。

当我运行spring-boot应用程序时,所有内容都存储在elasticsearch中,如果我通过owningFacilityId或projectId删除文档,则所有内容都会很好地同步,并且文档将被删除。

执行junit测试时会出现问题,该测试通过不删除数据通过拥有FacilityId / projectId功能来测试删除。

带注释的@Document的Elasticsearch Java映射类:

@Document(indexName = "search-object")
public class SearchObject implements Serializable {

    @Id
    private String id;

    private Long entityId;

    private SearchEntityType type;

    private String name;

    private Map<String, String> attributes = new HashMap<>();

    private Long owningFacilityId;

    private Long projectId;

// getter + setter 

ElasticSearchRepository:

public interface SearchEntityRepository extends ElasticsearchRepository<SearchObject, String> {

    SearchObject findFirstByEntityIdAndType(Long entityId, SearchEntityType type);

    void deleteByOwningFacilityId(Long owningFacilityId);

    void deleteByProjectId(Long projectId);

}

服务类实现

@Component
public class SearchEntityService {

    private final Logger log = LoggerFactory.getLogger(SearchEntityService.class);

    @Autowired
    private SearchEntityRepository searchEntityRepository;

    // ...





    public void deleteByOwningFacilityId(Long id) {
        log.debug("Start: delete by owning facility id {}", id);
        if (id != null) {
            searchEntityRepository.deleteByOwningFacilityId(id);
        }
        log.debug("End: delete by owning facility id {}", id);
    }
}

测试用例失败:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = LibalApp.class)
public class SearchEntityServiceTest {

    @Autowired
    private SearchEntityService searchEntityService;

    // ... 

    @Test
    @Transactional
    public void deleteByOwningFacilityId() {
        for (SearchEntityType type : SearchEntityType.values()) {
            searchEntityService.save(new SearchObject()
                .setProjectId(4l)
                .setOwningFacilityId(5l)
                .setEntityId(6l)
                .setName("DEFAULT SEARCH OBJECT")
                .setType(type)
                .addAttribute("ATTRIBUTE_KEY", "ATTRIBUTE VALUE"));
        }

        final Page<SearchObject> searchObjectsByProject = searchEntityService.search(4l, "*", PageRequest.of(0, SearchEntityType.values().length - 1));
        Assert.assertEquals(searchObjectsByProject.getTotalElements(), SearchEntityType.values().length);

        searchEntityService.deleteByOwningFacilityId(5l);

        final Page<SearchObject> searchObjectsByProjectAfterDeletion = searchEntityService.search(4l, "*", PageRequest.of(0, SearchEntityType.values().length - 1));
        Assert.assertEquals(0, searchObjectsByProjectAfterDeletion.getTotalElements());
    }
}

Junit-Runner输出(带有存储的文档)

---> SearchObject{id='ed18ec56-6087-4b59-a506-e6f784b3e872', entityId=6, type=FACILITY, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='d8b752aa-012d-4996-a676-7053d4539a5d', entityId=6, type=FLOOR, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='55b70315-0f6b-4cff-8de9-540e58f2af16', entityId=6, type=SPACE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='f8cc5f8b-a8e5-416e-a8d6-59237d6f7903', entityId=6, type=ASSET_COMPONENT, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='cf14acca-c2ee-4f40-9c6c-3f48609b88f4', entityId=6, type=TYPE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='e9633c4c-1c38-4ddc-83b1-ab1fb2ddf0f3', entityId=6, type=SYSTEM, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='6ccea72c-4504-4685-b45c-7c5d69576161', entityId=6, type=ZONE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='bc38c439-1dfd-44ae-85e8-744582f1b006', entityId=6, type=RESOURCE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='5fbd03d3-ee7d-4da4-9b21-6482b834a7ec', entityId=6, type=JOB, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='791b2191-95d8-44cf-9502-b474d652a224', entityId=6, type=SPARE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='552cac26-b4e3-4b77-a480-b4e845b57998', entityId=6, type=ISSUE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='fa7b3554-9e69-4e14-97fb-72aaf68251fd', entityId=6, type=IMPACT, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='c336b491-dd90-49ec-aaf8-eea7a1034a5a', entityId=6, type=DOCUMENT, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='13d5b32d-0ee9-4f30-b95c-3887bf773e72', entityId=6, type=ASSET_COMPONENT_ASSEMBLY, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='a19b1019-0a10-425a-bf0a-372b0f2f5b56', entityId=6, type=TYPE_ASSEMBLY, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='28d3fb54-e23f-44a3-9ba3-0d241840e052', entityId=6, type=CONNECTION, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='5ec26f46-7b43-4037-9559-ff735e42f249', entityId=6, type=COORDINATE, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}
---> SearchObject{id='71ab1b1d-06d0-4c43-a866-df745a73a900', entityId=6, type=CONTACT, name='DEFAULT SEARCH OBJECT', attributes={ATTRIBUTE_KEY=ATTRIBUTE VALUE}, owningFacilityId=5, projectId=4}

java.lang.AssertionError: 
Expected :0
Actual   :18
<Click to see difference>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:645)
    at org.junit.Assert.assertEquals(Assert.java:631)
    at de.libal.service.search.SearchEntityServiceTest.deleteByOwningFacilityId(SearchEntityServiceTest.java:239)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

依赖项

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <!-- <version>2.0.5.RELEASE</version> -->
        </dependency>
        <!-- Spring Data Jest dependencies for Elasticsearch -->
        <dependency>
            <groupId>com.github.vanroy</groupId>
            <artifactId>spring-boot-starter-data-jest</artifactId>
            <!-- <version>3.1.5.RELEASE</version> -->
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- log4j2-mock needed to create embedded elasticsearch instance with SLF4J -->
        <dependency>
            <groupId>de.dentrassi.elasticsearch</groupId>
            <artifactId>log4j2-mock</artifactId>
            <version>${log4j2-mock.version}</version>
            <scope>runtime</scope>
        </dependency>

从搜索方法中提取:

        final QueryBuilder projectMatchQuery = matchQuery("projectId", projectId);
        final BoolQueryBuilder searchTermShouldQuery = QueryBuilders.boolQuery()
            .minimumShouldMatch(1)
            .should(queryStringQuery(query));

        final BoolQueryBuilder must = QueryBuilders.boolQuery()
            .must(searchTermShouldQuery)
            .must(projectMatchQuery);

        return searchEntityRepository.search(must, pageable);

任何帮助或提示都会有所帮助。

elasticsearch spring-data spring-data-elasticsearch
1个回答
0
投票

我刚刚检查了执行deleteByOwningFacilityId()时执行的Spring Data Elasticsearch 3.0(旧版本)的代码:

    if(tree.isDelete()) {
        Object result = countOrGetDocumentsForDelete(query, accessor);
        elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType());
        return result;
    }

测试中缺少的是索引的刷新,您可以将服务实现更改为:

@Component
public class SearchEntityService {

    private final Logger log = LoggerFactory.getLogger(SearchEntityService.class);

    @Autowired
    private SearchEntityRepository searchEntityRepository;

    public void deleteByOwningFacilityId(Long id) {
        log.debug("Start: delete by owning facility id {}", id);
        if (id != null) {
            searchEntityRepository.deleteByOwningFacilityId(id);
            searchEntityRepository.refresh();                     // <----
        }
        log.debug("End: delete by owning facility id {}", id);
    }
}

在即将发布的Spring Data Elasticsearch第4版中,所有修改文档的存储库方法都将自动执行此刷新。

© www.soinside.com 2019 - 2024. All rights reserved.