1. add dependency
   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-neo4j</artifactId>
    </dependency>
  1. add Friend class

    import lombok.Data; import lombok.experimental.Accessors; import org.bson.types.ObjectId; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoId;

@Document(collection = "friend")
@Data
@Accessors(chain = true)
public class Friend {

    @MongoId
    private ObjectId id;
}
  1. startup exception

springboot 2.4.1 has no problem starting If the type of the id field of the Friend class is changed to String, the startup is OK **Test project address is https://github.com/star4j/test.git

Comment From: wilkinsona

This is the failure:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'neo4jMappingContext' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.mapping.MappingException: The property 'null' is not mapped to a Graph property!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:609) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.3.jar:5.3.3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.3.jar:5.3.3]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.2.jar:2.4.2]
    at com.example.test.TestApplication.main(TestApplication.java:10) [classes/:na]
Caused by: org.springframework.data.mapping.MappingException: The property 'null' is not mapped to a Graph property!
    at org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentProperty.getPropertyName(DefaultNeo4jPersistentProperty.java:247) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
    at org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity.computeIdDescription(DefaultNeo4jPersistentEntity.java:350) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
    at org.springframework.data.neo4j.core.mapping.DefaultNeo4jPersistentEntity.verify(DefaultNeo4jPersistentEntity.java:203) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:388) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.neo4j.core.mapping.Neo4jMappingContext.addPersistentEntity(Neo4jMappingContext.java:258) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:334) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_252]
    at org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:463) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.mapping.context.AbstractMappingContext.afterPropertiesSet(AbstractMappingContext.java:455) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1847) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784) ~[spring-beans-5.3.3.jar:5.3.3]
    ... 17 common frames omitted

For future reference, @star4j, please include this sort information when opening an issue as it helps us to process things more efficiently.

Comment From: wilkinsona

The change in behaviour is due to https://github.com/spring-projects/spring-boot/pull/24239.

@meistermeier Friend is now included in the initial entity set that's passed into Spring Data Neo4j's Neo4jMappingContext. It's then failing when processing the entity. Can you please take a look?

Comment From: meistermeier

Will do. :+1:

Comment From: meistermeier

First of you are correct in tracking this down to the recent change we introduced in Spring Boot. On the other side this was more or less just an alignment to the other stores and their auto configuration behaviour esp. to keep up with the scenarios if the mapping contexts are getting set explicitly into the strict mode. In those cases a registration of additional entities cannot be done later at runtime. Having said this, digging a little bit deeper into e.g. SD Mongo's definition of the Document annotation, I can see that the generic persistent type (annotation) gets inherited / declared. The change we introduced will now discover also Document annotated entities because they are also Persistent annotated. Discovering Persistent annotated entities is something that "every" (TBH I haven't checked all but for example https://github.com/spring-projects/spring-boot/blob/0104ee677ec5d9072948e3b6aa7ec9300945b49f/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.java#L51) other store also does. This means that a SD Mongo setup will also fail if we would inherit / decorate our very own annotations with Persistent. (This now gets longer than I have expected...but glad you are still here) My suggestion is that if an entity should not get discovered is either creating a Neo4jMappingContext or MongoMappingContext bean manually and providing the initial entity set (setInitialEntitySet) there. I would far less be in favour to go the defensive way and revert the changes because the stores are now aligned. What I would suggest, and can discuss with the Spring Data team, is that we talk about if and how to give users a more configuration-based way to separate the domain classes.

Comment From: wilkinsona

Thanks, @meistermeier.

While things are now aligned in terms of the annotations used when scanning, the behaviour when processing the results is not. For example, if I modify the supplied sample and replace Neo4j with Cassandra, the verification of the Friend entity performed in BasicCassandraPersistentEntity succeeds. In other words, Neo4j appears to be more restrictive in terms of the entities that will pass verification so the widening of the entities that are found (#24239) is now causing startup failures.

I think we either need to revert #24239 or Neo4j's verification needs to align with the other stores.

Comment From: meistermeier

Tried it with SD Cassandra and with the mongo/neo4j example provided ^^: Either replacing Neo4j with Cassandra or turning the example the other way around and making friend a Spring Data Neo4j Node (and removing the Document) will not result in an exception at startup but will register Friend also as an eligible entity for SD Cassandra/Mongo. Of course accessing a Cassandra table entity with the Mongo operations will fail during runtime with arbitrary mapping errors. I would suggest to "fix" the problem that we (you?) remove the Persistent annotation from the initialEntityClasses (we need to stick with the Node and the newly introduced RelationshipProperties). Additionally I had a chat with Mark about the overall usage of Persistent in the other modules and we will discuss a long-term solution that probably have an impact on all store modules configuration.

Comment From: wilkinsona

I would suggest to "fix" the problem that we (you?) remove the Persistent annotation from the initialEntityClasses

That makes sense to me. We can take care of that.

Additionally I had a chat with Mark about the overall usage of Persistent in the other modules and we will discuss a long-term solution that probably have an impact on all store modules configuration.

That sounds good too. Boot includes @Persistent when looking for Couchbase and Mongo entities. It's also included when looking for Cassandra entities but via code in CassandraEntityClassScanner which is part of Spring Data.

@mp911de Please let us know how we can track the long-term solution so that we can keep Boot's code in sync.

Comment From: mp911de

We'll discuss that topic within our team. I'm not sure why @Persistent-annotated entities were picked up in the first place. Once we've clarified that, we can proceed. In any case, scanning for @Persistent entities is rather an obstacle in multi-store arrangements.

Comment From: mp911de

We discussed that topic with the Spring Data team and concluded that we should remove @Persistent from the annotations that qualify for picking up a class as entity. Instead, we should use store-specific annotations. @Persistent is an SPI to be used by Spring Data store modules. We will update the affected Spring Data modules.

Comment From: wilkinsona

Thanks, Mark. Is there an issue that we can subscribe to so that we can align Boot with Data when the time comes?

Until that time, we'll use this issue to remove @Persistent from the Neo4j setup, i.e. we're going to partially revert #24239, keeping support for RelationshipProperties.

Comment From: mp911de

We need to check which modules are affected and file tickets where the scanning needs to be fixed. I'll leave references here once we have created tickets.