NotInTransactionException with basic relationship

93 views
Skip to first unread message

Michael Azerhad

unread,
Mar 19, 2013, 1:42:34 PM3/19/13
to ne...@googlegroups.com
I use Spring Data 2.2.0, Spring core 3.2.0 and Scala 2.10.

I struggle to add a relationship between two entities (User and meetings). 

Interesting excerpt of User.class:

@RelatedTo(`type` = "PARTICIPATES_IN")
  val meetings: java.util.Set[Meeting] = new java.util.HashSet[Meeting]()


def participateIn(meeting: Meeting) = {
    meeting.creator = this   // since bidirectional relation
    meetings.add(meeting)    //#needs_transaction      => throw an NotInTransactionException !! 
}

Sample Method making the relationship between entities (meeting is a newly created entity and I want it to be persisted while the relationship is made)

@Transactional
def save(meeting: Meeting): Meeting = {        
    val creator 
= userRepository.getUserBy_email("te...@test.com") // user retrieved (attached)
    creator
.participateIn(meeting) //attach a detached meeting entity                                           
    meeting
.creator = creator
    meetingRepository
.save(meeting)
}




It seems that the simple Transactional annotation isn't enough...

So, I think about my Spring configuration. 
Previously, it was that:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       
xmlns:context="http://www.springframework.org/schema/context"
       
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       
xmlns:tx="http://www.springframework.org/schema/tx"
       
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j
       http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>


    
<neo4j:config graphDatabaseService="graphDatabaseService"/>


    
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>


    
<tx:annotation-driven mode="aspectj" />


    
<neo4j:repositories base-package="repositories"/>


    
<context:spring-configured/>


    
<context:annotation-config/>
    
<context:component-scan base-package="controllers, applicationservices, models,repositories"/>




</beans>


So I opened the Spring Data for Neo4j documentation and I added one block to set up transactionManager:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       
xmlns:context="http://www.springframework.org/schema/context"
       
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       
xmlns:tx="http://www.springframework.org/schema/tx"
       
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j
       http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>


    
<neo4j:config graphDatabaseService="graphDatabaseService"/>   


    
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>


    
<bean id="neo4jTransactionManager" class="org.springframework.data.neo4j.config.JtaTransactionManagerFactoryBean">
        
<constructor-arg ref="graphDatabaseService"/>
    
</bean>
    
<tx:annotation-driven mode="aspectj" transaction-manager="neo4jTransactionManager"/>

    
<neo4j:repositories base-package="repositories"/>


    
<context:spring-configured/>


    
<context:annotation-config/>
    
<context:component-scan base-package="controllers, applicationservices, models,repositories"/>




</beans>

But I end up now with a ClassNotFoundError while parsing my applicationContext ...

How could I fix it? Did I miss something important?  

Thanks a lot.

Michael Azerhad

unread,
Mar 19, 2013, 5:00:56 PM3/19/13
to ne...@googlegroups.com
By debuggin Spring-data, I notice this thing:

public TransactionState getTransactionState()
   
{
       
Transaction tx;
       
try
       
{
            tx
= getTransaction();
       
}
       
catch ( SystemException e )
       
{
           
throw new RuntimeException( e );
       
}
       
return tx != null ? ((TransactionImpl)tx).getState() : TransactionState.NO_STATE;
   
}

tx is null... so NO_STATE is set as transactionState. Why doesn't it see the annotation @Transactional ? What should I add in my applicationContext or anything else to make it work?

Thanks.
Message has been deleted

Michael Azerhad

unread,
Mar 20, 2013, 5:39:31 AM3/20/13
to ne...@googlegroups.com
The total class of my Service is:

package applicationservices


import org.springframework.beans.factory.annotation.Autowired
import repositories.MeetingRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import scalaz._, Scalaz._
import utils.ScalaCloseableIterable


@Service
class MeetingServices {


 
@Autowired
 
var meetingRepository: MeetingRepository = _


 
@Transactional(readOnly = true)
 
def findAll() = {
   
new ScalaCloseableIterable(meetingRepository.findAll()).toList
 
}



 
@Transactional  def save(meeting: Meeting): Meeting = {        
      val creator
= userRepository.getUserBy_email("te...@test.com") // user retrieved (attached)
      creator
.participateIn(meeting) //attach a detached meeting entity                                          
      meeting
.creator = creator
      meetingRepository
.save(meeting)
 
}
}

On Tuesday, March 19, 2013 6:42:34 PM UTC+1, Michael Azerhad wrote:

Michael Hunger

unread,
Mar 20, 2013, 5:59:13 AM3/20/13
to ne...@googlegroups.com
How is your service injected and used.


--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Michael Azerhad

unread,
Mar 20, 2013, 6:15:27 AM3/20/13
to ne...@googlegroups.com
Ok, I've just written a simple test (surely ugly :)) in scala showing my service call: (reproducing the NotInTransactionException)

def testMethodSavingAMeetingWithItsCreator = {
    val meetingServices
= new ClassPathXmlApplicationContext("application-context-test.xml")..getBean("meetingServices", classOf[MeetingServices])
    val user
= userRepository.getUserBy_email("te...@test.com")  // user well retrieved
    val possibleMeeting
= Meeting.create("title", "description", "activityType", (new DateTime(2013, 2, 13, 21, 30), new DateTime(2013, 2, 13, 22, 30)), "place", 2)
     
(meetingServices.save(possibleMeeting.toOption.get, user)) match {              // call MeetingServices's save method
       
case Success(s) =>
       
case Failure(e) => println(e.list(0).cause.get); println(e.list(0).msg)  // enter in this failure case, since a NotInTransaction occured in the save method
     
}
 
}

Michael Azerhad

unread,
Mar 20, 2013, 6:43:54 AM3/20/13
to ne...@googlegroups.com
And my application-context-test.xml is the following:  <?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       
xmlns:context="http://www.springframework.org/schema/context"
       
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       
xmlns:tx="http://www.springframework.org/schema/tx"
       
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j
       http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>


   
<neo4j:config graphDatabaseService="graphDatabaseService"/>


   
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase" destroy-method="shutdown"/>


   
<tx:annotation-driven mode="aspectj" />

   
<neo4j:repositories base-package="repositories"/>

   
<context:spring-configured/>
   
<context:annotation-config/>

   
<context:component-scan base-package="applicationservices, repositories"/>


</beans>

Michael Hunger

unread,
Mar 20, 2013, 8:19:44 AM3/20/13
to ne...@googlegroups.com
Can you put all that together in a project for us to try?


Cheers

Michael

(neo4j.org) <-[:WORKS_ON]- (@mesirii) -[:TAKES_CARE_OF]-> (you) -[:WORKS_WITH]->(@Neo4j)



Michael Azerhad

unread,
Mar 20, 2013, 9:22:25 AM3/20/13
to ne...@googlegroups.com
Yes, I am currently writting a light sample project reproducing the issue and I push it up to a github repository  as soon as I finish (few times), I will signal it :)

Thanks :)

Michael Hunger

unread,
Mar 20, 2013, 9:34:30 AM3/20/13
to ne...@googlegroups.com
Thanks a lot!

Michael

Michael Azerhad

unread,
Mar 20, 2013, 12:00:16 PM3/20/13
to ne...@googlegroups.com
I put a complete demo of the issue here:  https://github.com/mica16/TransactionNeo4JIssue.git

It is based on an embeddedGraphDatabase (path: target/neo4jgraph).

The whole is commented inside.

You can clone it and just run an : sbt update run        

Thanks to you :)

I'm pretty sure, that I missed some configuration in my applicationContext ... or maybe I use the SpringData api badly ;)

Michael

Michael Azerhad

unread,
Mar 20, 2013, 6:05:21 PM3/20/13
to ne...@googlegroups.com
I tried to add a configuration for aspectJ transactions like this:




   
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase">
       
<constructor-arg value="target/neo4jgraph" />
   
</bean>



   
<neo4j:config graphDatabaseService="graphDatabaseService" />



   
<bean id="neo4jTransactionManager"
       
class="org.springframework.transaction.jta.JtaTransactionManager">
       
<property name="transactionManager">
           
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">

               
<constructor-arg ref="graphDatabaseService" />
           
</bean>

       
</property>
       
<property name="userTransaction">
           
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">

               
<constructor-arg ref="graphDatabaseService" />
           
</bean>

       
</property>

   
</bean>


   
<tx:annotation-driven mode="aspectj"
       
transaction-manager="neo4jTransactionManager" />




   
<neo4j:repositories base-package="repositories"/>


   
<context:spring-configured/>


   
<context:annotation-config/>

   
<context:component-scan base-package="services, repositories"/>


</beans>

But it still leads to a NotInTransactionException.... really stuck on this :s

Michael Azerhad

unread,
Mar 21, 2013, 8:09:15 AM3/21/13
to ne...@googlegroups.com
Adding @Fetch to the User's meetings collection make the whole works, but .... I don't want eager loading.

I'm pretty sure that there @Transaction is not take into account :(

@Transactional
 
def save(meeting: Meeting) {
    val creator
= userRepository.getUserByEmail("te...@test.com")
    meetingRepository
.save(meeting)
    creator
.participateIn(meeting)

What I expect here, is that creator object is attached to transaction, since retrieved within it. Therefore, lazy collection should be work, when doing: meetings.add(meeting) within participateIn method.

I found this post...similar to my issue:

Thanks for the help :)

Michael Hunger

unread,
Mar 21, 2013, 11:14:57 AM3/21/13
to ne...@googlegroups.com
It is take into account I rather think sth between spring and scala gets in the way

I'm in meetings all day will look at it as soon as I find time

Sent from mobile device

Michael Azerhad

unread,
Mar 21, 2013, 5:46:53 PM3/21/13
to ne...@googlegroups.com
Ok :)

I've just tested with a Java version.

Same exception....

Michael
Reply all
Reply to author
Forward
0 new messages