Apache Gremlin Обновление свойства приводит к добавлению свойства, не поддерживаемому при обновлении вершины - PullRequest
0 голосов
/ 28 ноября 2018

Вот ошибка, с которой я сталкиваюсь.

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[IllegalStateException: Property addition is not supported]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:251)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:178)
    at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:363)
    at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:361)
    at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
    at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
Caused by: java.lang.IllegalStateException: Property addition is not supported
    at org.apache.tinkerpop.gremlin.structure.Element$Exceptions.propertyAdditionNotSupported(Element.java:133)
    at org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex.property(DetachedVertex.java:91)
    at org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex.property(DetachedVertex.java:50)
    at gremlin.scala.ScalaElement.$anonfun$updateWith$2(ScalaElement.scala:76)
    at scala.collection.immutable.HashMap$HashMap1.foreach(HashMap.scala:231)
    at scala.collection.immutable.HashMap$HashTrieMap.foreach(HashMap.scala:462)
    at gremlin.scala.ScalaElement.updateWith(ScalaElement.scala:76)
    at gremlin.scala.ScalaElement.updateWith$(ScalaElement.scala:70)
    at gremlin.scala.ScalaVertex.updateWith(ScalaVertex.scala:8)
    at gremlin.scala.ScalaElement.updateAs(ScalaElement.scala:82)

Вот мои модели и то, как я их определил.

import java.util. UUID
import gremlin.scala.{Element, Marshallable, Vertex, id, label, underlying}


@label("trip")
case class TripModel(tripId: Option[String] = None,
                     name: String,
                     createdDate: java.time.Instant = java.time.Instant.now(),
                     startDate: java.time.Instant,
                     duration: Int,
                     totalAdults: Int,
                     totalChildrens: Int,
                     @underlying vertex: Option[Vertex] = None
                    )

object TripModel {

  implicit val marshaller = new Marshallable[TripModel] {
    def toCC(element: Element): TripModel = {
      val tripId = Some(element.value[UUID]("tripId").toString)
      val tripName = element.value[String]("name")
      val duration =  element.value[Int]("duration")
      val totalAdults = element.value[Short]("totalAdults")
      val totalChildren =element.value[Short]("totalChildrens")
      val date = element.value[java.time.Instant]("createdDate")
      val startDate = element.value[java.time.Instant]("startDate")

      models.TripModel(tripId = tripId, name = tripName,
        startDate  = startDate, duration = duration,
        totalAdults = totalAdults, totalChildrens = totalChildren, createdDate = date)
    }

    override def fromCC(cc: TripModel): FromCC = {
      val values = Map("name" -> cc.name,
        "createdDate" -> cc.createdDate,
        "startDate" -> cc.startDate,
        "duration"-> cc.duration,
        "totalAdults" -> cc.totalAdults,
        "totalChildrens" -> cc.totalChildrens,
        "tripId" -> UUID.fromString(cc.tripId.get).toString)
      FromCC(None, "trip", values)
    }
  }
}

И способ обновления вершины:следующим образом

def updateTripDetails(id:String, tripUpdate: UpdateTripRequest) = {
    implicit val g = db.g

    val item = db.g.V().has(KeyValue(tripId, id)).head
    item.updateAs[TripModel](cc => cc.copy(name = tripUpdate.tripName.getOrElse(cc.name)))
  }

Я пытаюсь обновить определенное свойство вершины, однако я всегда получал вышеупомянутую ошибку.Есть ли обходной путь для этого?

Я подключаюсь к серверу gremlin.Вот как я строю соединение.

class GrDbConnection @Inject()  (config: Configuration) {

  private val dseCluster = DseCluster.builder()
    .addContactPoints(config.get[String]("dse.cluster.address"))
    .withPort(config.get[Int]("dse.cluster.port"))
    .build()

  private val graphName = "graphName"
  private val graphOptions = new GraphOptions().setGraphName(graphName)
  private val session = dseCluster.connect()

  session.executeGraph(new SimpleGraphStatement("schema.config().option('graph.schema_mode').set('development')").setGraphName(graphName))
  session.executeGraph(new SimpleGraphStatement("schema.config().option('graph.allow_scan').set('true')").setGraphName(graphName))
  // Create a ScalaGraph from a remote Traversal Source using withRemote
  // See: http://tinkerpop.apache.org/docs/current/reference/#connecting-via-remotegraph for more details
  private val connection = DseRemoteConnection.builder(session).withGraphOptions(graphOptions).build()
  val g:ScalaGraph = EmptyGraph.instance().asScala
    .configure(_.withRemote(connection))
}

1 Ответ

0 голосов
/ 28 ноября 2018

Вы не показываете, как вы создаете g, но я предполагаю, что вы подключаетесь к удаленному графу (например, граф размещен на Gremlin Server), а не к внедренному, поэтому в этом случае эта строка:

val item = db.g.V().has(KeyValue(tripId, id)).head

возвращает DetachedVertex.Он не знает графа, с которым он связан, и поэтому вы можете думать о нем как о доступном только для чтения.Вы не обновляете его свойства напрямую, вы используете Gremlin для своих обновлений.Я не знаю, как playframework обрабатывает базовые обновления, но держу пари, что он не ожидает «отключенных» элементов и предполагает локальный экземпляр встроенного графа и, следовательно, элементы, которые знают о своем графе хоста.

Тем не менее, правильный способ обновить свойства вершины - просто использовать Gremlin, а не напрямую работать с самим объектом Vertex, и поэтому вы бы предпочли обновление следующим образом:

g.V(item).property('name', 'some name')
...