使用spring-data-neo4j时的MappingException

时间:2015-03-24 13:56:17

标签: spring-boot spring-data-neo4j

最近我用spring-data-neo4j写了一个小电影推荐演示。 但我坚持奇怪的MappingException。 异常堆栈跟踪如下所示。

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:675)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:690)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.liudonghua.apps.neo4j_data_importer.Application.main(Application.java:202)
Caused by: org.springframework.data.mapping.model.MappingException: Setting property user to com.liudonghua.apps.neo4j_data_importer.domain.Movie@66286c8 on com.liudonghua.apps.neo4j_data_importer.domain.Rating@618519cf
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:85)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:91)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$2.doWithAssociation(SourceStateTransmitter.java:61)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:337)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:112)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:104)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:192)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:250)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
    at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:357)
    at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory$RelatedToViaCollectionFieldAccessor.persistEntities(RelatedToViaCollectionFieldAccessorFactory.java:99)
    at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory$RelatedToViaCollectionFieldAccessor.setValue(RelatedToViaCollectionFieldAccessorFactory.java:93)
    at org.springframework.data.neo4j.fieldaccess.DefaultEntityState.setValue(DefaultEntityState.java:113)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setEntityStateValue(SourceStateTransmitter.java:70)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$100(SourceStateTransmitter.java:40)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$4.doWithAssociation(SourceStateTransmitter.java:113)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:337)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesTo(SourceStateTransmitter.java:109)
    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:357)
    at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:351)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:91)
    at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:416)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:401)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy52.save(Unknown Source)
    at com.liudonghua.apps.neo4j_data_importer.Application.run(Application.java:109)
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:672)
    ... 5 common frames omitted
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type com.liudonghua.apps.neo4j_data_importer.domain.Movie to type com.liudonghua.apps.neo4j_data_importer.domain.User
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:311)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:173)
    at org.springframework.data.mapping.model.BeanWrapper.getPotentiallyConvertedValue(BeanWrapper.java:157)
    at org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:75)
    at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:83)
    ... 53 common frames omitted

以下是一些相关的代码。

@NodeEntity
public class Movie {

    @GraphId
    Long nodeId;

    @Indexed
    private long id;

    @Indexed
    private String title;
    private Date releaseDate;
    private String imdbUrl;

    @RelatedTo(type="HAS_GENRE")
    @Fetch
    Set<Genre> genres;

    @RelatedToVia(type="RATED" ,direction=Direction.INCOMING)
    @Fetch
    Set<Rating> ratings;

    public Movie() {
    }

    public Movie(long id, String title, Date releaseDate, String imdbUrl,
            Set<Genre> genres) {
        this.id = id;
        this.title = title;
        this.releaseDate = releaseDate;
        this.imdbUrl = imdbUrl;
        this.genres = genres;
    }

    // getters and setters are omitted here.
}

@RelationshipEntity(type = "RATED")
public class Rating {

    @GraphId
    Long relationId;

    @Indexed
    private long id;

    private int rate;

    @StartNode
    private User user;

    @EndNode
    private Movie movie;

    public Rating() {
    }

    public Rating(User user, Movie movie, int rate) {
        this.user = user;
        this.movie = movie;
        this.rate = rate;
    }

    // getters and setters are omitted here.
}

@NodeEntity
public class User {

    @GraphId
    Long nodeId;

    @Indexed
    private long id;
    private int age;
    private String gender;
    private String occupation;
    private String zipCode;

    // http://stackoverflow.com/questions/28641586/spring-data-neo4j-cant-create-two-relationship-properties-with-same-label
    @RelatedTo(type="RATED")
    @Fetch
    private Set<Movie> movies;

    @RelatedToVia(type="RATED")
    @Fetch
    private Set<Rating> ratings;


    public User() {
    }

    public User(long id, int age, String gender, String occupation,
            String zipCode) {
        this.id = id;
        this.age = age;
        this.gender = gender;
        this.occupation = occupation;
        this.zipCode = zipCode;
    }

    public Rating rate(Movie movie, int rate) {
        Rating rating = new Rating(this, movie, rate);
        ratings.add(rating);
        return rating;
    }

    // getters and setters are omitted here.
}

public interface UserRepository extends GraphRepository<User> {

}

Movie movie = movieRepository.save(new Movie(...));
User user = userRepository.save(new User(...));
...
user.rate(movie, 3);
userRepository.save(user);  // This line throws exception

以下是我的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.liudonghua.apps</groupId>
	<artifactId>neo4j-data-importer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>neo4j-data-importer</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<jdk.version>1.8</jdk.version>
	</properties>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.2.2.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-neo4j</artifactId>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>

	</build>

	<repositories>
		<repository>
			<id>spring-releases</id>
			<name>Spring Releases</name>
			<url>http://repo.spring.io/libs-release</url>
		</repository>
		<repository>
			<id>neo4j</id>
			<name>Neo4j</name>
			<url>http://m2.neo4j.org/</url>
		</repository>
	</repositories>

	<pluginRepositories>
		<pluginRepository>
			<id>spring-releases</id>
			<name>Spring Releases</name>
			<url>http://repo.spring.io/libs-release</url>
		</pluginRepository>
	</pluginRepositories>
</project>

1 个答案:

答案 0 :(得分:0)

最后,我通过覆盖正确的equals,hashCode方法并提供完整的getter和setter来解决这个问题。