Warm tip: This article is reproduced from serverfault.com, please click

Required identifier property not found for class Person, when using Neo4j ogm?

发布于 2021-03-31 02:01:40

I'm new to neo4j. From what I've read so far I understand that it's generally bad practise to use the default <id> parameter externally of my app. I'd therefore like to be able to specify my own personId parameter separate of <id>. To do this, I'd like to use neo4j-ogm, however I'm getting this exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'personController' defined in file [/Users/freid/www/project/address-book/build/classes/java/main/com/addressbook/controller/PersonController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository' defined in com.addressbook.repositories.PersonRepository defined in @EnableNeo4jRepositories declared on SetupBeans: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Required identifier property not found for class com.addressbook.model.Person!
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar:5.3.5]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar:5.3.5]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) ~[spring-boot-2.4.4.jar:2.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-2.4.4.jar:2.4.4]
        at com.addressbook.Application.main(Application.java:17) ~[main/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository' defined in com.addressbook.repositories.PersonRepository defined in @EnableNeo4jRepositories declared on SetupBeans: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Required identifier property not found for class com.addressbook.model.Person!
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5]
        ... 20 common frames omitted
Caused by: java.lang.IllegalStateException: Required identifier property not found for class com.addressbook.model.Person!
        at org.springframework.data.mapping.PersistentEntity.getRequiredIdProperty(PersistentEntity.java:105) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.repository.core.support.PersistentEntityInformation.getIdType(PersistentEntityInformation.java:74) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.neo4j.repository.support.Neo4jRepositoryFactory.getTargetRepository(Neo4jRepositoryFactory.java:67) ~[spring-data-neo4j-6.0.6.jar:6.0.6]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:281) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329) ~[spring-data-commons-2.4.6.jar:2.4.6]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.5.jar:5.3.5]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.5.jar:5.3.5]
        ... 31 common frames omitted`

Here is my Person node:

package com.addressbook.model;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.neo4j.ogm.annotation.*;

import java.util.Set;

@NodeEntity
@Getter
@Setter
public class Person {
    @Id
    @GeneratedValue
    Long personId;

    @Builder
    public Person(Long personId, String firstName, String lastName, Integer age) {
        this.personId = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    @NotEmpty(message = "Please provide a first name")
    String firstName;

    @NotEmpty(message = "Please provide a last name")
    String lastName;

    @Min(value = 18, message = "Age should not be less than 18")
    @Max(value = 150, message = "Age should not be greater than 150")
    Integer age;

    @Relationship(type = "SPOUSE",direction=Relationship.OUTGOING)
    public Set<Person> spouse;

    @Relationship(type = "SIBLING",direction=Relationship.OUTGOING)
    public Set<Person> sibling;

    @Relationship(type = "FAMILY",direction=Relationship.OUTGOING)
    public Set<Person> family;
}

Here is my Person repository:

package com.addressbook.repositories;

import com.addressbook.model.Person;
import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface PersonRepository extends Neo4jRepository<Person, Long> {}

And, here is my Person controller:

package com.addressbook.controller;

import com.addressbook.exception.NotFoundException;
import com.addressbook.model.Person;
import com.addressbook.repositories.PersonRepository;
import com.addressbook.model.View;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import lombok.extern.log4j.Log4j2;
import javax.validation.*;

@Log4j2
@RestController
@RequestMapping("/api/v1")
@Api(tags = { "Person" })
public class PersonController {

    private final PersonRepository personRepository;

    @Autowired
    public PersonController(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @GetMapping("person/{personId}")
    @ResponseStatus(HttpStatus.OK)
    public ResponseEntity<Person> getPerson(@PathVariable("personId") Long id) throws NotFoundException {
        Person person = this.personRepository.findById(id).orElseThrow(() -> new NotFoundException("Person not found!"));

        return new ResponseEntity(person, HttpStatus.OK);
    }

}

This exception only seems to occurs when I use org.neo4j.ogm.annotation.Id annotation. If I use the org.springframework.data.neo4j.core.schema.Id annotation then I can create and retrieve entities. But, it only seems to create the entity with the default <id>, which is not what I want.

My understanding, which maybe wrong, is that org.neo4j.ogm.annotation.Id should allow you to add your own id separate of <id>, and even allow you to combine it with org.neo4j.ogm.id.UuidStrategy to use a uuid for entities. Is this correct?

I'm not sure why the exception says Required identifier property not found for class com.addressbook.model.Person! as I thought the org.neo4j.ogm.annotation.Id annotation would satisfy this.

Any help would be appreciated.

Questioner
Freid001
Viewed
0
aldrin 2021-03-31 12:34:57

It is possible that you are mixing the earlier neo4j-ogm with the latest Spring Data Neo4j

Check your dependencies and make sure your annotations are from the correct packages (for instance, org.springframework.data.neo4j.*)

If you follow the instructions in the link above, you should be able to resolve your errors.