Ошибка при вставке объекта через REST API с помощью Spring Boot и Neo4j - PullRequest
0 голосов
/ 28 сентября 2018

Я тестирую Neo4j с Spring Boot и обнаружил следующую проблему при попытке вставить элемент, используя Rest API, я получаю сообщение об ошибке, что JSON не может быть сериализован в Entity.Если кто-то может мне помочь или объяснить, как изменить мой код или как сериализовать эту сущность, я был бы очень благодарен.Мои классы ... Пользовательский объект

@NodeEntity
public class User extends AbstractEntity{

    @Id
    @GeneratedValue
    private Long id;

    private String firstname, lastname;


    @NotNull @NotBlank @Email
    @Index(unique = true)
    private String email;

    @Index(unique = true)
    private String phone;

    @Relationship(type = "ADDRESS")
    private Set<Address> addresses = new HashSet<>();

    public User() {
    }
    //get & set & const....
    }

Адресный объект

@NodeEntity
public class Address extends AbstractEntity{
    /*Update the OMG [https://neo4j.com/developer/neo4j-ogm] and remove de id.
     Keep the id in AbstractEntity*/
    @Id
    @GeneratedValue
    private Long id;

    private String street, city;

    @Relationship(type = "COUNTRY")
    private Country country;

    public Address(String street, String city, Country country) {
        this.street = street;
        this.city = city;
        this.country = country;
    }

    public Address() {
    }
    //get & set & const...
    }

Страна субъекта

@NodeEntity
public class Country extends AbstractEntity {
    /*Update the OMG [https://neo4j.com/developer/neo4j-ogm] and remove de id.
     Keep the id in AbstractEntity*/
    @Id
    @GeneratedValue
    private Long id;

    @Index(unique=true)
    private String code;

    private String name;

    public Country(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public Country() {
    } 
  }

Абстрактный объект

@EnableNeo4jAuditing
public abstract class AbstractEntity {

    public abstract Long getId();

    @Transient
    private SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");

    private Date created = new Date();

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }

        if (getId() == null || obj == null || !getClass().equals(obj.getClass())) {
            return false;
        }
        return getId().equals(((AbstractEntity) obj).getId());

    }

    @Override
    public int hashCode() {
        return getId() == null ? 0 : getId().hashCode();
    }
}

Мой простой класс репозитория для пользователей магазина

public interface UserRepository extends Neo4jRepository<User, Long> {

    User findByFirstname(String name);

    @Override
    void delete(User deleted);
}

Мой класс обслуживания

@Service
public class UserService {
     private UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public Iterable<User> contact() {
        return userRepository.findAll();
    }
    public User save(User user) {
            userRepository.save(user);
            return user;
    }
    public User show(Long id) {
        return userRepository.findById(id).get();
    }
    public User update(Long id, User user) {
        User c = userRepository.findById(id).get();
        if(user.getFirstname()!=null && !user.getFirstname().trim().isEmpty())
            c.setFirstname(user.getFirstname().trim());
        if(user.getLastname()!=null && !user.getLastname().trim().isEmpty())
            c.setLastname(user.getLastname().trim());
        if(user.getEmail()!=null && !user.getEmail().trim().isEmpty())
            c.setEmail(user.getEmail().trim());
        userRepository.save(c);
        return user;
    }
    public String delete(Long id) {
        User user = userRepository.findById(id).get();
        userRepository.delete(user);

        return "";
    }
}

Мой класс контроллера

@RestController
public class UserController {
    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET, value = "/users")
    public Iterable<User> user() {
        return userService.contact();
    }

    @RequestMapping(method = RequestMethod.POST, value = "/users")
    public String save(@RequestBody User user) {
        try {
            userService.save(user);
        }catch (org.neo4j.driver.v1.exceptions.ClientException ex){
            System.err.println("******||||||||||||[{   The User exist with the same email   }]||||||||||||******");
        return "The User exist with the same email";
        }
        return user.toString();
    }
    @RequestMapping(method=RequestMethod.GET, value="/users/{id}")
    public User show(@PathVariable Long id) {
        try{
        return userService.show(id);}
        catch (java.util.NoSuchElementException ex){
            System.err.println("******||||||||||||[{   The User do not exist    }]||||||||||||******");
        }
        return null;
    }
    @RequestMapping(method=RequestMethod.PUT, value="/users/{id}")
    public User update(@PathVariable Long id, @RequestBody User user) {
        return userService.update(id, user);
    }
    @RequestMapping(method=RequestMethod.DELETE, value="/users/{id}")
    public String delete(@PathVariable Long id) {
        return userService.delete(id);
    }

}

Это моя простая схема, которую я пытаюсьмодель (Neo4j - это база данных NoSQL без контура, но я пытаюсь смоделировать простое приложение) введите описание изображения здесь

Когда он пытался протестировать методы остальных API, ону меня работает, но сущность Country не сериализована в json.

У меня уже есть данные, вставленные в базу данных, что я и сделал, используя тестовый метод, объявляющий объекты и использующий методы для его сохранения.Проблема возникает, когда я использую формат JSON.Когда я запускаю команду curl, чтобы протестировать Rest API, она не возвращает страну

$ curl -i -H "Accept: application/json" localhost:8088/users/1
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 27 Sep 2018 20:38:31 GMT

{"created":"2018-09-27T19:55:21.578+0000","id":1,"firstname":"Yuniel","lastname":"Acosta Pérez","email":"yuniel.acosta@someserver.com","phone":"+999999999999","addresses":[{"created":"2018-09-27T19:55:21.578+0000","id":0,"street":"Some Stree","city":"Some City","country":null}]}

Как видите, страна возвращает ее как нулевое значение, и если оно существует в базе данных.

Когда я попытался вставить элемент с помощью API, он посетовал на ошибку, что я не могу сериализовать объект страны в JSON.

$ curl -i -X POST -H "Content-Type: application/json" -d '{"firstname":"Yuniel","lastname":"Acosta Pérez","email":"yuniel.acosta@someserver.com","phone":"+999999999999","addresses":[{"street":"Some Stree","city":"Some City","country":[{"code":"OO","name":"ANYCOUNTRY"}]}]}' localhost:8088/users

Следующая ошибка - это та, которая выбрасывает меня

{"timestamp": "2018-09-27T21: 07: 56.365 + 0000", "status": 400, "error": "Bad Request", "message": "Ошибка синтаксического анализа JSON: Невозможно десериализовать экземплярcom.syskayzen.hypercube.domain.Address из токена START_ARRAY; вложенное исключение - com.fasterxml.jackson.databind.exc.MismatchedInputException: Невозможно десериализовать экземпляр com.syskayzen.hypercube.domain.Address из токена START_ARRAY \ n в [Source: (PushbackInputStream); строка: 1, столбец: 122] (через цепочку ссылок: com.syskayzen.hypercube.domain.User [\ "address \"]) "," путь ":" / users "}

Если вы можете сказать мне, как решитьпроблема в том, как сериализовать страну или если по другой причинеошибка.

Я использую Spring Boot 2.0.5 и Spring Data Neo4j

1 Ответ

0 голосов
/ 05 октября 2018

Я полагаю, что причина, по которой страна возвращается в ноль в вашей команде curl, заключается в том, что запрос в базе данных занимает всего 1 прыжок.Итак, он тянет пользователя, затем идет 1 прыжок, чтобы потянуть узел адреса, но затем он останавливается.Чтобы он выполнял больше прыжков вдоль пути, вам нужно указать глубину.

Вы можете сделать это, указав глубину в команде curl и добавив параметр для 'int deep', чтобы передать внизвызов хранилища.Это позволит вам иметь динамическую глубину, если вы добавите в приложение больше прыжков, которые вы хотите получить.

Метод службы будет выглядеть примерно так ...

public User show(Long id, int depth) {
        return userRepository.findById(id, depth).get();
}

Документация для этого находится по следующей ссылке: https://docs.spring.io/spring-data/neo4j/docs/5.1.0.RELEASE/reference/html/#reference:session:persisting-entities:save-depth

...