我是一个Neo4j / Spring数据新手,如果这是显而易见的事情,我很抱歉,但我看到这里和那里,并不能弄清楚它是否是一个错误或功能。 我正在使用SDN 3.1.0和Neo4j 2.0.4,现在在内存中运行(用于测试)。
我有一个超级简单的POJO,我尝试使用SDN保存到Neo4j中。它看起来像这样:
@NodeEntity
public class Weekday {
@GraphId
private Long id;
@Indexed(unique = true)
public DayOfWeek weekdayCode;
}
当我使其非唯一索引或根本没有索引时,一切都很美妙。当我将它设为String时,它可以使用唯一约束。 (好吧,有点,我知道它不会抛出异常而是默默地更新现有的 - 这不是完美的但我发现JIRA问题与此相关)。不幸的是,当我尝试将其保存为具有唯一约束的枚举时,我得到一个例外:
org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement MERGE (n:`Weekday` {`weekdayCode`: {value}}) ON CREATE SET n={props} return n; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement MERGE (n:`Weekday` {`weekdayCode`: {value}}) ON CREATE SET n={props} return n; nested exception is java.lang.IllegalArgumentException: [MONDAY:java.time.DayOfWeek] is not a supported property value
at org.springframework.data.neo4j.support.query.CypherQueryEngineImpl.query(CypherQueryEngineImpl.java:61)
at org.springframework.data.neo4j.support.schema.SchemaIndexProvider.merge(SchemaIndexProvider.java:114)
at [...]
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement MERGE (n:`Weekday` {`weekdayCode`: {value}}) ON CREATE SET n={props} return n; nested exception is java.lang.IllegalArgumentException: [MONDAY:java.time.DayOfWeek] is not a supported property value
at org.springframework.data.neo4j.support.query.CypherQueryEngineImpl.parseAndExecuteQuery(CypherQueryEngineImpl.java:72)
at org.springframework.data.neo4j.support.query.CypherQueryEngineImpl.query(CypherQueryEngineImpl.java:58)
... 63 more
Caused by: java.lang.IllegalArgumentException: [MONDAY:java.time.DayOfWeek] is not a supported property value
at org.neo4j.kernel.api.properties.PropertyConversion.convertProperty(PropertyConversion.java:107)
at org.neo4j.kernel.api.properties.Property.property(Property.java:51)
at [...]
据我所知,这是因为将唯一字段放入地图“props”中,并且地图的内容不会自动转换,因此它会向Neo4j发送枚举,这显然不会等。
答案 0 :(得分:3)
我不确定它是不是真正的错误,但是我使用自己的Enum类时遇到了类似的问题。
所以,你可以尝试这样的事情:
首先创建您的转换器,如:
@Component
public class StringToDayOfWeekConverter implements Converter<String, DayOfWeek> {
@Override
public DayOfWeek convert(String source) {
return DayOfWeek.valueOf(source);
}
}
@Component
public class DayOfWeekToStringConverter implements Converter<DayOfWeek, String> {
@Override
public String convert(DayOfWeek source) {
return source.name();
}
}
然后你注册转换器,所以neo4j可以使用它们:
@Configuration
@EnableNeo4jRepositories("my.repository.package")
@EnableTransactionManagement
public class MyNeo4jConfiguration extends Neo4jConfiguration {
@Autowired
private StringToDayOfWeekConverter stringToDayOfWeekConverter;
@Autowired
private DayOfWeekToStringConverter dayOfWeekToStringConverter;
@Override
protected ConversionService neo4jConversionService() throws Exception {
ConverterRegistry converterRegistry = (ConverterRegistry) super.neo4jConversionService();
converterRegistry.addConverter(stringToDayOfWeekConverter);
converterRegistry.addConverter(dayOfWeekToStringConverter);
return (ConversionService) converterRegistry;
}
}
答案 1 :(得分:0)
创建一个转换器扩展EnumStringConverter,如下所示:
package com.noopu.pyramid.domain.model.converter;
import com..pyramid.common.UserType;
import org.neo4j.ogm.typeconversion.EnumStringConverter;
public class UserTypeStringConverter extends EnumStringConverter {
public UserTypeStringConverter ( ) {
super ( UserType.class );
}
}
并使用@Converter注释,例如:
package com.noopu.pyramid.domain.model;
import com.noopu.pyramid.common.UserType;
import com.noopu.pyramid.domain.model.converter.UserTypeStringConverter;
import lombok.Data;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.Index;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.typeconversion.Convert;
import java.io.Serializable;
@NodeEntity
@Data
public class User implements Serializable {
private static final long serialVersionUID = 8979348201709416439L;
@GraphId
private Long graphId;
@Index
protected Long id;
@Index(unique = true)
private Long uid;
@Index(unique = true)
private String phone;
@Index
@Convert(UserTypeStringConverter.class)
private UserType type;
}