Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring Data Neo4j - Exception when trying to use @Transactional annotation
    text
    copied!<p>I'm quite new with Spring Data and Neo4j, and there is something i don't understand about using the @Transactional annotation. It seems that i must declare an empty constructor for a class which i annotated one of its methods with @Transactional, and I also need to create an empty constructor for the node entities classes that the transaction will use... (and if i don't declare the empty constructors, i get an exception). But.. maybe i'm missing something. I'll show you an example, below is a code for example, which demonstrates what i'm talking about (Its a short spring-data-neo4j setup that gets things up and running):</p> <p>My configuration class:</p> <pre><code>@Configuration @ComponentScan(basePackages={"org.technion.socialrescue.core"}) @ImportResource("spring-data-context.xml") @EnableTransactionManagement public class DefaultApplicationConfig { @Bean(destroyMethod = "shutdown") public GraphDatabaseService graphDatabaseService() { return new EmbeddedGraphDatabase("target/graph.db"); } } </code></pre> <p>the spring-data-context.xml file:</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:neo4j="http://www.springframework.org/schema/data/neo4j" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd"&gt; &lt;neo4j:config graphDatabaseService="graphDatabaseService" /&gt; &lt;neo4j:repositories base-package="org.technion.socialrescue" /&gt; &lt;/beans&gt; </code></pre> <p>The class that hosts the method that is marked with @Transactional:</p> <pre><code>@Component("someClass") public class SomeClass { public SomeObjectRepository someObjects; @Autowired public SomeClass(SomeObjectRepository someOBjects) { this.someObjects = someOBjects; } @Transactional public void someMethod() { someObjects.save(new SomeObject("roy")); } } </code></pre> <p>the SomeObject class (which will be used as a node in the graph):</p> <pre><code>@NodeEntity public class SomeObject { public SomeObject(String name) { this.name = name; } @GraphId private Long id; @Indexed String name; } </code></pre> <p>The SomeObjectRepository interface:</p> <pre><code>package org.technion.socialrescue.core; import org.springframework.data.neo4j.repository.GraphRepository; public interface SomeObjectRepository extends GraphRepository&lt;SomeObject&gt; { } </code></pre> <p>and the code that launch the application:</p> <pre><code>public class Playground { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DefaultApplicationConfig.class); SomeClass someClass = (SomeClass)context.getBean("someClass"); someClass.someMethod(); context.close(); } } </code></pre> <p>So, by running the code above, I'm getting the following exception:</p> <pre><code>Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someClass' defined in file [C:\Users\t-rvelic\workspace\social-rescue\target\classes\org\technion\socialrescue\core\SomeClass.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.technion.socialrescue.core.SomeClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.context.annotation.AnnotationConfigApplicationContext.&lt;init&gt;(AnnotationConfigApplicationContext.java:73) at org.technion.socialrescue.playground.Playground.main(Playground.java:13) Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.technion.socialrescue.core.SomeClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:217) at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ... 10 more Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721) at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499) at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) ... 17 more </code></pre> <p>So i tried to follow the cause for this exception, and added an empty constructor for <code>SomeClass</code>, so it looks like this:</p> <pre><code>@Component("someClass") public class SomeClass { public SomeObjectRepository someObjects; public SomeClass() { } @Autowired public SomeClass(SomeObjectRepository someOBjects) { this.someObjects = someOBjects; } @Transactional public void someMethod() { someObjects.save(new SomeObject("roy")); } } </code></pre> <p>Then, i launched again my app, and got the following exception:</p> <pre><code>Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: SomeObject: entity must have a no-arg constructor.; nested exception is java.lang.IllegalArgumentException: SomeObject: entity must have a no-arg constructor. at org.springframework.data.neo4j.support.Neo4jExceptionTranslator.translateExceptionIfPossible(Neo4jExceptionTranslator.java:43) at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy39.save(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 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.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy40.save(Unknown Source) at org.technion.socialrescue.core.SomeClass.someMethod(SomeClass.java:23) at org.technion.socialrescue.core.SomeClass$$FastClassByCGLIB$$d9c3b9ef.invoke(&lt;generated&gt;) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 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.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631) at org.technion.socialrescue.core.SomeClass$$EnhancerByCGLIB$$d5a7b8cd.someMethod(&lt;generated&gt;) at org.technion.socialrescue.playground.Playground.main(Playground.java:17) Caused by: java.lang.IllegalArgumentException: SomeObject: entity must have a no-arg constructor. at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator$1.create(AbstractConstructorEntityInstantiator.java:87) at org.springframework.data.neo4j.support.mapping.AbstractConstructorEntityInstantiator.createEntityFromState(AbstractConstructorEntityInstantiator.java:56) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedInstantiator.createEntityFromState(Neo4jEntityPersister.java:135) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedInstantiator.createEntityFromState(Neo4jEntityPersister.java:122) at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:86) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:244) at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231) at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:293) at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:287) at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:109) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318) 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) ... 28 more </code></pre> <p>So this time, i added an empty constructor for the <code>SomeObject</code> class, it looks like that:</p> <pre><code>@NodeEntity public class SomeObject { public SomeObject() { } public SomeObject(String name) { this.name = name; } @GraphId private Long id; @Indexed String name; } </code></pre> <p>And then it worked... </p> <p>But why it worked? why i had to add two empty constructors? I tried to google it, found nothing. I really want to know why it behaves like that... any help will be highly appreciated!</p> <p>Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload