Amit
Amit

Reputation: 34725

Spring Neo4j: Error in "neo4jTemplate.save()"

I am using spring-neo4j-data in my java project. I am getting the following error while saving an entity:

Versions:

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j</artifactId>
        <version>3.0.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j-rest</artifactId>
        <version>3.0.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-lucene-index</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-kernel</artifactId>
        <version>2.0.1</version>
    </dependency>

Code:

User Entity:

@NodeEntity
public class User  {

    @GraphId
    Long id;

    @Indexed(unique=true)
    private String uid;

    private String name;
    private UserDetails userDetails;

    @RelatedToVia(type = "FRIEND", direction = Direction.BOTH)
    private Set<Friendship> friendships;

    @RelatedToVia(type = "FOLLOWS", direction = Direction.OUTGOING)
    private Set<Follows> follows;

    public User() {
    }

    public User(String uid) {
        this.uid = uid;
    }

    public Friendship friendOf(Neo4jOperations template, User friend, FriendshipType friendshipType) {
        final Friendship friendship = template.createRelationshipBetween(this, friend, Friendship.class, "FRIEND", false);
        friendship.addFriendshipType(friendshipType);
        return template.save(friendship);
    }

    public Follows follows(Neo4jOperations template, User following, FollowerType followerType) {
        final Follows follows = template.createRelationshipBetween(this, following, Follows.class, "FOLLOWS", false);
        follows.addFollowerType(followerType);
        return template.save(follows);
    }

    // Getters and Setters start
    public Long getId() {
        return id;
    }

    public String getUid() {
        return uid;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setUserDetails(UserDetails userDetails) {
        this.userDetails = userDetails;
    }

    public UserDetails getUserDetails() {
        return userDetails;
    }

    public Set<Friendship> getFriendships() {
        return friendships;
    }

    // Getters and Setters end

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (obj == null || obj.getClass() != this.getClass())
            return false;

        User user = (User) obj;
        return this.getUid().equals(user.getUid());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 3;
        result = prime * result + this.getUid().hashCode();
        return result;
    }

}

Friendship Pojo:

@RelationshipEntity(type = "FRIEND")
public class Friendship {

    @GraphId
    private Long id;

    @StartNode
    private User u1;

    @StartNode
    private User u2;

    private Set<FriendshipType> friendshipTypes;

//    public Friends(User u1, User u2, FriendshipType... friendshipTypes) {
//        this.u1 = u1;
//        this.u2 = u2;
//        this.friendshipTypes = new HashSet<>();
//        for (FriendshipType type : friendshipTypes)
//            this.friendshipTypes.add(type);
//    }

    public void addFriendshipType(FriendshipType friendshipType) {
        if (friendshipTypes == null)
            friendshipTypes = new HashSet<>();
        friendshipTypes.add(friendshipType);
    }

}

Test:

public class Test {
    private void run(Neo4jTemplate template) {
        User john = new User("john_uid");
        template.save(john);
    }
}

Exception:

Exception in thread "main" java.lang.NullPointerException
at org.springframework.data.neo4j.fieldaccess.RelationshipEntities.<init>(RelationshipEntities.java:46)
at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory$RelatedToViaCollectionFieldAccessor.<init>(RelatedToViaCollectionFieldAccessorFactory.java:74)
at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory.forField(RelatedToViaCollectionFieldAccessorFactory.java:56)
at org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryProviders$FieldAccessorFactoryProvider.accessor(FieldAccessorFactoryProviders.java:46)
at org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryProviders.getFieldAccessors(FieldAccessorFactoryProviders.java:74)
at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.<init>(DefaultEntityState.java:52)
at org.springframework.data.neo4j.support.node.NodeEntityState.<init>(NodeEntityState.java:38)
at org.springframework.data.neo4j.support.node.NodeEntityStateFactory.getEntityState(NodeEntityStateFactory.java:48)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:98)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:167)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:243)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:311)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:305)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:358)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy35.save(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
at com.sun.proxy.$Proxy47.save(Unknown Source)
at com.music.Test.run(Test.java:43)
at com.music.Test.main(Test.java:37)

Upvotes: 0

Views: 364

Answers (1)

Michael Hunger
Michael Hunger

Reputation: 41676

There also seems to be code missing, as it complains about relationship-entities.

Perhaps you can share a project on github or so that exhibits the issue?

Some of your code was also wrong, I fixed it below. Also you can just use repo.save() to uniquely create an entity.

@NodeEntity
public class User  {

    @GraphId
    Long id;

    @Indexed(unique=true)
    private String uid;

    public User(String uid) {
        this.uid = uid;
    }
}

public interface UserRepository extends GraphRepository<User> {

    public User getUserByUid(String userId);

    @Query(
        "MERGE (user:User {userId:{0}} RETURN user"
    )
    public User createUserIfNotExists(String userId);
}

public class Test {
    private void run(UserRepository userRepository) {
        User john = new User("john_uid");
        userRepository.save(john);
    }
}

Regarding your relationship-entity, you have a copy&paste typo, you have @StartNode twice.

@StartNode
private User u1;

@StartNode
private User u2;

Upvotes: 1

Related Questions