嵌入式Neo4j删除节点和Lucene遗留索引 - node_auto_indexing不同步问题

时间:2015-04-06 20:15:30

标签: lucene neo4j cypher spring-data-neo4j

我正在尝试使用node_auto_indexing中的字段删除节点。 当我尝试使用repository.delete(id)删除节点时。 在那之后我试图通过它的id删除Node并且我得到以下异常:

java.lang.IllegalStateException: This index (Index[__rel_types__,Relationship]) has been marked as deleted in this transaction
    at org.neo4j.index.impl.lucene.LuceneTransaction$DeletedTxDataBoth.illegalStateException(LuceneTransaction.java:475)
    at org.neo4j.index.impl.lucene.LuceneTransaction$DeletedTxDataBoth.removed(LuceneTransaction.java:470)
    at org.neo4j.index.impl.lucene.LuceneTransaction.remove(LuceneTransaction.java:112)
    at org.neo4j.index.impl.lucene.LuceneXaConnection.remove(LuceneXaConnection.java:116)
    at org.neo4j.index.impl.lucene.LuceneIndex.remove(LuceneIndex.java:215)
    at org.springframework.data.neo4j.support.typerepresentation.AbstractIndexBasedTypeRepresentationStrategy.remove(AbstractIndexBasedTypeRepresentationStrategy.java:113)
    at org.springframework.data.neo4j.support.typerepresentation.AbstractIndexBasedTypeRepresentationStrategy.preEntityRemoval(AbstractIndexBasedTypeRepresentationStrategy.java:100)
    at org.springframework.data.neo4j.support.mapping.EntityRemover.removeRelationship(EntityRemover.java:63)
    at org.springframework.data.neo4j.support.mapping.EntityRemover.removeNode(EntityRemover.java:51)
    at org.springframework.data.neo4j.support.mapping.EntityRemover.removeNodeEntity(EntityRemover.java:45)
    at org.springframework.data.neo4j.support.mapping.EntityRemover.remove(EntityRemover.java:85)
    at org.springframework.data.neo4j.support.Neo4jTemplate.delete(Neo4jTemplate.java:267)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:276)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:282)

此外,当我尝试通过Cypher查询删除节点时

@Query("MATCH ()-[r]-(p:Product) WHERE id(p) = {productId} DELETE r, p")
void deleteProduct(@Param("productId") Long productId);

我通过其Id:

查看此已删除的节点后收到另一个异常
java.lang.IllegalStateException: No primary SDN label exists .. (i.e one starting with _) 
    at org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeTypeRepresentationStrategy.readAliasFrom(LabelBasedNodeTypeRepresentationStrategy.java:126)
    at org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeTypeRepresentationStrategy.readAliasFrom(LabelBasedNodeTypeRepresentationStrategy.java:39)
    at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:36)
    at org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor.readAliasFrom(TRSTypeAliasAccessor.java:26)
    at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:102)
    at org.springframework.data.convert.DefaultTypeMapper.getDefaultedTypeToBeUsed(DefaultTypeMapper.java:165)
    at org.springframework.data.convert.DefaultTypeMapper.readType(DefaultTypeMapper.java:142)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:78)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
    at org.springframework.data.neo4j.support.Neo4jTemplate.createEntityFromState(Neo4jTemplate.java:224)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.createEntity(AbstractGraphRepository.java:62)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.findOne(AbstractGraphRepository.java:127)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.delete(AbstractGraphRepository.java:282)

如何正确删除参与Lucene Legacy Indexing node_auto_indexing的节点?如何从Lucene索引中删除此节点?

更新:

这是我的Neo4jConfig

@Configuration
@EnableNeo4jRepositories(basePackages = "com.example")
@EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration implements BeanFactoryAware {

    @Resource
    private Environment environment;

    private BeanFactory beanFactory;

    public Neo4jConfig() {
        setBasePackage("com.example");
    }

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {

        GraphDatabaseService graphDb = new GraphDatabaseFactory()
                .newEmbeddedDatabaseBuilder("target/example-test-db")
                .setConfig(GraphDatabaseSettings.node_keys_indexable, "name,description")
                .setConfig(GraphDatabaseSettings.node_auto_indexing, "true")
                .newGraphDatabase();

        return graphDb;
    }

    /**
     * Hook into the application lifecycle and register listeners that perform
     * behaviour across types of entities during this life cycle
     * 
     */
    @Bean
    protected ApplicationListener<BeforeSaveEvent<BaseEntity>> beforeSaveEventApplicationListener() {
        return new ApplicationListener<BeforeSaveEvent<BaseEntity>>() {
            @Override
            public void onApplicationEvent(BeforeSaveEvent<BaseEntity> event) {
                BaseEntity entity = event.getEntity();
                if (entity.getCreateDate() == null) {
                    entity.setCreateDate(new Date());
                } else {
                    entity.setUpdateDate(new Date());
                }
            }
        };
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

}

项目中实体的基础实体:

public class BaseEntity {

    private Date createDate;

    private Date updateDate;

    public BaseEntity() {
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }

}

和我尝试删除的Vote实体:

@NodeEntity
public class Vote extends BaseEntity {

    private static final String VOTED_ON = "VOTED_ON";
    private final static String VOTED_FOR = "VOTED_FOR";
    private static final String CREATED_BY = "CREATED_BY";

    @GraphId
    private Long id;

    @RelatedTo(type = VOTED_FOR, direction = Direction.OUTGOING)
    private Decision decision;

    @RelatedTo(type = VOTED_ON, direction = Direction.OUTGOING)
    private Criterion criterion;

    @RelatedTo(type = CREATED_BY, direction = Direction.OUTGOING)
    private User author;

    private double weight;

    private String description;

    public Vote() {
    }

    public Vote(Decision decision, Criterion criterion, User author, double weight, String description) {
        this.decision = decision;
        this.criterion = criterion;
        this.author = author;
        this.weight = weight;
        this.description = description;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Decision getDecision() {
        return decision;
    }

    public void setDecision(Decision decision) {
        this.decision = decision;
    }

    public Criterion getCriterion() {
        return criterion;
    }

    public void setCriterion(Criterion criterion) {
        this.criterion = criterion;
    }

    public User getAuthor() {
        return author;
    }

    public void setAuthor(User author) {
        this.author = author;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Vote vote = (Vote) o;
        if (id == null)
            return super.equals(o);
        return id.equals(vote.id);
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : super.hashCode();
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

}

1 个答案:

答案 0 :(得分:0)

感谢@MichaelHunger和Neo4j,此问题已在Neo4j 2.2.2和SDN 3.4.0.M1修复