简体   繁体   English

让spring-data-neo4j使用getter和setter

[英]Getting spring-data-neo4j to use getters and setters

Hey there fellow Stackoverflower, 嘿,那里有Stackoverflower,

I recently tried to use Spring's Spring.Data.Neo4j Connector in conjunction with the Neo4J database. 我最近尝试将Spring的Spring.Data.Neo4j连接器与Neo4J数据库结合使用。 After getting configuration right, I encountered the following problem. 正确配置后,我遇到了以下问题。 When storing my JavaFX-based entity, the JavaFX properties were set to null. 存储基于JavaFX的实体时,JavaFX属性设置为null。 This is most likely the case because spring.data.neo4j doesn't seem to use getters and setters, but reflection instead. 这很可能是因为spring.data.neo4j似乎不使用getter和setter,而是使用反射。 Since it doesn't know how to persist JavaFX properties, it persists null values and overwrites them when retrieving from the DB. 由于它不知道如何持久保存JavaFX属性,因此它会保留空值并在从数据库检索时覆盖它们。

This is my Entity 这是我的实体

@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);
    }
}

Is it possible to get Spring.data.neo4j to use getters and setters for access, so that I can persist my JavaFX beans? 是否有可能让Spring.data.neo4j使用getter和setter进行访问,以便我可以持久化我的JavaFX bean? Or am I doing something wrong? 或者我做错了什么?

Thanks for helping, Karl 谢谢你的帮助,卡尔

Right now SDN just uses the fields of your entity, something like this would be a configurable change. 现在SDN只使用你的实体的字段,这样的东西将是一个可配置的变化。 Feel free to raise an issue on JIRA for implementing it. 随意在JIRA上提出实施问题。

The issue could depend on how Spring Data Neo4j maps fields that are references to objects of classes that are not node entities, ie not annotated with @NodeEntity. 问题可能取决于Spring Data Neo4j如何映射对非节点实体的类的对象的引用的字段,即未使用@NodeEntity注释。 In this case the referred class must be convertible to String ( see documentation ). 在这种情况下,引用的类必须可以转换为String( 参见文档 )。 I've had a similar issue and I solved it declaring a Spring conversion factory that manages mapping from the referred class to String and back. 我有一个类似的问题,我解决了它声明一个Spring转换工厂,管理从引用类到String的映射和返回。 This is an example mapping every class that extends an Embedded interface (it's void, just to mark the class as embeddable) to String and viceversa: 这是一个示例,它将每个扩展嵌入式接口的类(它是无效的,只是为了将类标记为可嵌入的)映射到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;
            }
        }
    }
}

The conversion factories should be declared in the Neo4j configuration file as follows: 应在Neo4j配置文件中声明转换工厂,如下所示:

<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="EmbeddedToStringConverterFactory"/>
            <bean class="StringToEmbeddedConverterFactory"/>
        </list>
    </property>
</bean>

I had the same problem with StringProperty in my bean. 我的bean中的StringProperty遇到了同样的问题。 The answer from @remigio helped me to find a solution. @remigio的答案帮助我找到了解决方案。

So I added the converter factories: 所以我添加了转换器工厂:

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;
        }
     }
  }
}

Then I registered those converter factories in my Neo4jConfiguration: 然后我在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());
    }
}

What I don't like is that I had to call the method afterPropertiesSet() . 我不喜欢的是我必须调用afterPropertiesSet()的方法。 Maybe there is a more elegant way. 也许有更优雅的方式。 But after all it works and the properties are saved. 但毕竟它有效并且属性得以保存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM