嘿,那伙伴Stackoverflower,
我最近尝试将Spring的Spring.Data.Neo4j连接器与Neo4J数据库结合使用。正确配置后,我遇到了以下问题。存储基于JavaFX的实体时,JavaFX属性设置为null。这很可能是因为spring.data.neo4j似乎不使用getter和setter,而是使用反射。由于它不知道如何持久化JavaFX属性,因此它会保留空值并在从数据库中检索时覆盖它们。
这是我的实体
@NodeEntity
public class User implements UserIF {
@GraphId
private Long id = null;
private final StringProperty nameProperty = new SimpleStringProperty();
public String getName() {
return nameProperty.get();
}
public void setName(String name) {
nameProperty.set(name);
}
}
是否可以让Spring.data.neo4j使用getter和setter进行访问,以便我可以持久化我的JavaFX bean?或者我做错了什么?
感谢您的帮助, 卡尔
答案 0 :(得分:1)
现在SDN只使用您实体的字段,类似这样的内容将是可配置的更改。请随意在JIRA上提出实施问题。
答案 1 :(得分:1)
问题可能取决于Spring Data Neo4j如何映射对非节点实体的类对象的引用的字段,即未使用@NodeEntity注释。 在这种情况下,引用的类必须可转换为String(see documentation)。 我有一个类似的问题,我解决了它声明一个Spring转换工厂,管理从引用类到String的映射和返回。 这是一个示例,它映射每个扩展嵌入式接口的类(它是无效的,只是为了将类标记为可嵌入)到String,反之亦然:
final class EmbeddedToStringConverterFactory implements ConverterFactory<Embedded, String> {
@Override
public <T extends String> Converter<Embedded, T> getConverter(Class<T> type) {
return new EmbeddedToStringConverter(type);
}
private final class EmbeddedToStringConverter<E extends Embedded, S extends String> implements Converter<E, S> {
private Class<S> stringType;
public EmbeddedToStringConverter(Class<S> stringType) {
this.stringType = stringType;
}
@Override
public S convert(E source) {
if (source != null) {
return (S) new Gson().toJson(source);
} else {
return null;
}
}
}
}
final class StringToEmbeddedConverterFactory implements ConverterFactory<String, Embedded> {
@Override
public <T extends Embedded> Converter<String, T> getConverter(Class<T> type) {
return new StringToEmbeddedConverter(type);
}
private final class StringToEmbeddedConverter<S extends String, E extends Embedded> implements Converter<S, E> {
private Class<E> embeddedType;
public StringToEmbeddedConverter(Class<E> embeddedType) {
this.embeddedType = embeddedType;
}
@Override
public E convert(S source) {
if (source != null) {
return (E) new Gson().fromJson(source, embeddedType);
} else {
return null;
}
}
}
}
转换工厂应在Neo4j配置文件中声明如下:
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="EmbeddedToStringConverterFactory"/>
<bean class="StringToEmbeddedConverterFactory"/>
</list>
</property>
</bean>
答案 2 :(得分:0)
我的bean中的StringProperty遇到了同样的问题。 @remigio的答案帮助我找到了解决方案。
所以我添加了转换器工厂:
public class StringPropertyToStringConverterFactory
implements ConverterFactory<StringProperty, String> {
@Override
public <T extends String> Converter<StringProperty, T> getConverter(final Class<T> type) {
return new StringPropertyToStringConverter<>();
}
private final class StringPropertyToStringConverter<E extends StringProperty, S extends String>
implements Converter<E, S> {
@Override
public S convert(final E s) {
if (s != null) {
return (S) s.getValue();
} else {
return null;
}
}
}
}
public class StringToStringPropertyConverterFactory
implements ConverterFactory<String, StringProperty> {
@Override
public <T extends StringProperty> Converter<String, T> getConverter(final Class<T> type) {
return new StringToStringPropertyConverter<>();
}
private final class StringToStringPropertyConverter<S extends String, E extends StringProperty>
implements Converter<S, E> {
@Override
public E convert(final S s) {
if (s != null) {
return (E) new SimpleStringProperty(s);
} else {
return null;
}
}
}
}
然后我在Neo4jConfiguration中注册了这些转换器工厂:
public class AppConfig extends Neo4jConfiguration {
public AppConfig() {
setBasePackage("org.foo.bar");
addConversionService();
}
private void addConversionService() {
ConversionServiceFactoryBean conversionService = new ConversionServiceFactoryBean();
conversionService.setConverters(
newHashSet(new StringPropertyToStringConverterFactory(),
new StringToStringPropertyConverterFactory()));
conversionService.afterPropertiesSet();
setConversionService(conversionService.getObject());
}
}
我不喜欢的是我必须调用方法afterPropertiesSet()
。也许有更优雅的方式。但毕竟它有效并且属性得以保存。