scala和spring数据neo4j - 没有为Field配置FieldAccessor

时间:2014-02-21 18:49:44

标签: java spring scala spring-data-neo4j

我正在使用spring-data-neo4j库开发scala项目。

首先,这是我的`build.sbt

name := """scheduling-backend"""

version := "1.0"

scalaVersion := "2.10.2"

resolvers += "spray repo" at "http://repo.spray.io"

resolvers += "spray nightlies" at "http://nightlies.spray.io"

resolvers += "SpringSource Milestone Repository" at "http://repo.springsource.org/milestone"

resolvers += "Neo4j Cypher DSL Repository" at "http://m2.neo4j.org/content/repositories/releases"

libraryDependencies ++= Seq(
  "com.typesafe.akka"  %% "akka-actor"       % "2.2.0",
  "com.typesafe.akka"  %% "akka-slf4j"       % "2.2.0",
  "ch.qos.logback"      % "logback-classic"  % "1.0.13",
  "io.spray"            % "spray-can"        % "1.2-20130712",
  "io.spray"            % "spray-routing"    % "1.2-20130712",
  "io.spray"           %% "spray-json"       % "1.2.3",
  "org.specs2"         %% "specs2"           % "1.14"         % "test",
  "io.spray"            % "spray-testkit"    % "1.2-20130712" % "test",
  "com.typesafe.akka"  %% "akka-testkit"     % "2.2.0"        % "test",
  "com.novocode"        % "junit-interface"  % "0.7"          % "test->default",
  "org.springframework.scala" % "spring-scala" % "1.0.0.M2",
  "org.springframework.data" % "spring-data-neo4j" % "2.3.3.RELEASE",
  "org.springframework.data" % "spring-data-neo4j-rest" % "2.3.3.RELEASE",
  "javax.validation" % "validation-api" % "1.1.0.Final",
  "com.github.nscala-time" %% "nscala-time" % "0.8.0"
)

scalacOptions ++= Seq(
  "-unchecked",
  "-deprecation",
  "-Xlint",
  "-Ywarn-dead-code",
  "-language:_",
  "-target:jvm-1.7",
  "-encoding", "UTF-8"
)

testOptions += Tests.Argument(TestFrameworks.JUnit, "-v")

现在,这是我试图坚持的实体

trait EntityID {
  @GraphId
  var id: java.lang.Long = _
}

@NodeEntity
class Leg() extends EntityID{

  var name: String = _
  var superName:String = _
  @GraphProperty(propertyType = classOf[java.lang.Long])
  var date: DateTime = _
}

以及我用来测试所有内容的代码:

package persistence

import org.junit.runner.RunWith
import org.specs2.runner._
import org.springframework.context.ApplicationContext
import org.specs2.mutable.Specification
import org.springframework.context.support.ClassPathXmlApplicationContext
import org.neo4j.graphdb.GraphDatabaseService
import org.joda.time.DateTime

@RunWith(classOf[JUnitRunner])
class SpringDataTest extends Specification {
  "SpringData should" >> {

    "work" in {
      val ctx2: ApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml")
      val repository = ctx2.getBean(classOf[LegRepository])
      val oldLeg = new Leg
      oldLeg.date = DateTime.now
      oldLeg.name = "newName"
      oldLeg.superName = "asd"
      repository.save(oldLeg)
      val newLeg = repository.findOne(5)
      newLeg.name must beEqualTo("newName")
      success
    }
  }


}

现在,当我试着坚持我的对象时,我会进入日志:

19:46:57.288 [specs2.DefaultExecutionStrategy1] INFO  o.s.d.n.f.DelegatingFieldAccessorFactory - No FieldAccessor configured for field: class org.joda.time.DateTime date rel: false idx: false

因此访问DateTime属性时似乎存在一些问题,但是当我使用Web界面查看数据库时,保存String属性很有意思。

我还创建了DateTime类型的转换为Long

package persistence

import org.springframework.core.convert.converter.Converter
import org.joda.time.DateTime
import java.lang

class DateTimeConverter extends Converter[DateTime, java.lang.Long]{
  override def convert(source: DateTime): lang.Long = source.getMillis
}

但它没有帮助'

编辑:请求.xml配置

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/data/neo4j
            http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">

    <context:annotation-config/>

    <bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
        <constructor-arg value="http://localhost:7474/db/data/" index="0"/>
    </bean>

    <neo4j:config graphDatabaseService="graphDatabaseService"/>
    <neo4j:repositories base-package="persistence"/>

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="persistence.DateTimeConverter"/>
            </set>
        </property>
    </bean>

</beans>

1 个答案:

答案 0 :(得分:1)

我们需要双向转换器。你的只是一个方向。

在java.util.Date的SDN示例中:

public void addConverters(ConversionService service) {
    if (service instanceof ConverterRegistry) {
        ConverterRegistry registry = (ConverterRegistry) service;
        registry.addConverter(new DateToStringConverter());
        registry.addConverter(new DateToLongConverter());
        registry.addConverter(new StringToDateConverter());
        registry.addConverter(new NumberToDateConverter());
        registry.addConverter(new EnumToStringConverter());
        registry.addConverterFactory(new StringToEnumConverterFactory());
    } else {
        throw new IllegalArgumentException("conversionservice is no ConverterRegistry:" + service);
    }
}


public static class DateToLongConverter implements Converter<Date, Long> {

    @Override
    public Long convert(Date source) {
        return source.getTime();
    }
}

public static class NumberToDateConverter implements Converter<Number, Date> {

    @Override
    public Date convert(Number source) {
        return new Date(source.longValue());
    }
}

检查如下

public boolean isSerializablePropertyField(final ConversionService conversionService) {
    if (isRelationship()) return false;
    final Class<?> type = getType();
    if (getTypeInformation().isCollectionLike()) {
        return isConvertible(conversionService, getComponentType());
    }
    return isConvertible(conversionService, type);
}

private boolean isConvertible(ConversionService conversionService, Class<?> type) {
    return conversionService.canConvert(type, propertyType) && conversionService.canConvert(propertyType, type);
}