某些节点连接没有通过 SpringData

问题描述

我对 Java 和 Spring 非常陌生,所以我尝试制作一个简单的应用程序,以链接列表样式向车辆添加车辆测量值:

Desired Structure

我在确定是否使用 springframework.data.neo4j 注释的 neo4j.ogm 注释时遇到了很多麻烦。目前我决定使用 springframework 注释,因为 ogm 会导致不正确的 Id execption。在我的代码片段中,我将类似的成员合并到同一个片段中以减少冗余。

这是我的 build.gradle:

plugins {
    id 'org.springframework.boot' version '2.4.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-neo4j'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
}

test {
    useJUnitPlatform()
}

这是我的应用程序根目录:

package com.example.neo4j;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;

@SpringBootApplication
@EnableNeo4jRepositories
public class Test2Application {

    public static void main(String[] args) {
        SpringApplication.run(Test2Application.class,args);
    }

    @Bean
    CommandLineRunner demo(VehicleRepository vehicleRepository,VehicleMeasurementRepository vehicleMeasurementRepository,VehicleMeasurementService vehicleMeasurementService) {
        return args -> {
            vehicleRepository.deleteall();
            vehicleMeasurementRepository.deleteall();

            Vehicle vehicle = new Vehicle("vin","Ford","bronco");
            vehicleRepository.save(vehicle);

            VehicleMeasurement first = new VehicleMeasurement(5D,198D,100D);
            VehicleMeasurement second = new VehicleMeasurement(10D,98D);
            VehicleMeasurement third = new VehicleMeasurement(15D,97D);

            vehicleMeasurementService.addNewMeasurementByVin("vin",third);
            vehicleMeasurementService.addNewMeasurementByVin("vin",second);
            vehicleMeasurementService.addNewMeasurementByVin("vin",first);
        };
    }
}

这是我的实体:

package com.example.neo4j;

import lombok.Data;
import lombok.NoArgsConstructor;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;


@Data
@Node
@NoArgsConstructor
public class Vehicle {

    @Id @GeneratedValue
    private Long id;

    private String vin,make,model;

    public Vehicle(String vin,String make,String model) {
        this.vin = vin;
        this.make = make;
        this.model = model;
    }


    @Relationship(type = "HAS_HEAD_MEASUREMENT",direction = Relationship.Direction.OUTGOING)
    @JsonIgnoreProperties({"next","prevIoUs"})
    private VehicleMeasurement head;


    @Relationship(type = "HAS_TAIL_MEASUREMENT","prevIoUs"})
    private VehicleMeasurement tail;
    public VehicleMeasurement getHead() {
        return head;
    }
}

@Node
@Data
@NoArgsConstructor
public class VehicleMeasurement {

    @Id @GeneratedValue
    private Long id;

    private Double mileage,engineTemperature,oilLife;

    public VehicleMeasurement(Double mileage,Double engineTemperature,Double oilLife) {
        this.mileage = mileage;
        this.engineTemperature = engineTemperature;
        this.oilLife = oilLife;
    }

    @Relationship(type = "NEXT",direction = Relationship.Direction.OUTGOING)
    @JsonIgnoreProperties({"head","tail","vehicleHeadReference","vehicleTailReference"})
    private VehicleMeasurement next;
}

这是我的存储库:

package com.example.neo4j;

import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;

import java.util.List;

public interface VehicleRepository extends Neo4jRepository<Vehicle,Long> {
    Vehicle findVehicleByVin(String vin);
}

public interface VehicleMeasurementRepository extends Neo4jRepository<VehicleMeasurement,Long> {

    @Query("MATCH (v:Vehicle {vin: $vin})-[*]->(vm:VehicleMeasurement)-[*]-(v)" +
            "RETURN disTINCT vm ORDER BY vm.mileage ASCENDING")
    List<VehicleMeasurement> findVehicleMeasurementsByVehicleVin(String vin);
}

这是我的服务:

package com.example.neo4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.Optional;

@Service
public class VehicleMeasurementService {

    @Autowired
    VehicleMeasurementRepository vehicleMeasurementRepository;

    @Autowired
    VehicleRepository vehicleRepository;

    public void addNewMeasurementByVin(String vin,VehicleMeasurement measurement) {
        Vehicle targetVehicle = vehicleRepository.findVehicleByVin(vin);

        Iterator<VehicleMeasurement> vehicleMeasurements = vehicleMeasurementRepository.findVehicleMeasurementsByVehicleVin(vin).iterator();

        Optional<VehicleMeasurement> left = Optional.empty();
        Optional<VehicleMeasurement> right = Optional.empty();

        while (vehicleMeasurements.hasNext()) {
            var next = vehicleMeasurements.next();

            if (next.getMileage() <= measurement.getMileage()) {
                left = Optional.of(next);
            }

            if (measurement.getMileage() <= next.getMileage() && right.isEmpty()) {
                right = Optional.of(next);
            }
        }

        if (left.isEmpty() && right.isEmpty()){
            targetVehicle.setHead(measurement);
            targetVehicle.setTail(measurement);
        } else if (left.isEmpty()) {
            targetVehicle.setHead(measurement);
            measurement.setNext(right.get());
            vehicleMeasurementRepository.save(right.get());
        } else if (right.isEmpty()) {
            VehicleMeasurement leftValue = left.get();
            leftValue.setNext(measurement);
            vehicleMeasurementRepository.save(leftValue);
            targetVehicle.setTail(measurement);
        }

        vehicleMeasurementRepository.save(measurement);
        vehicleRepository.save(targetVehicle);
    }
}

我运行 add 方法 3 次并在它们之间进行调试以查看这些结果:

result after first rendition


enter image description here


enter image description here


最后一张图片是问题所在,当我在调试过程中深入节点时,我看到了我期望的引用,但随后它完成了运行,节点 98 和节点 97 之间的连接不存在。

任何建议都将不胜感激,无论是风格、用法还是方法都有帮助。我预计我会错误地使用弹簧数据。我尝试使用两种方式引用进行再现,但它会破坏堆栈,即使我的忽略属性注释也是如此。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)