Results 1 to 8 of 8

Thread: Object not saving in Neo4j DB with repository.save() call within a Transaction

  1. #1
    Join Date
    Jan 2009
    Location
    Huntington Beach, CA
    Posts
    718

    Default Object not saving in Neo4j DB with repository.save() call within a Transaction

    For some reason my object changes aren't being saved/reflected in the database and I am not sure why.

    Here is my UserRepository

    Code:
    public interface UserRepository extends GraphRepository<User>,
            RelationshipOperationsRepository<User>,
            EventGateUserDetailsService {
    Which gives me my save method.

    Here is my Service code that is wrapped in a Transaction. I have @Transactional at the class level and this method is part of the interface that the service implements.

    Code:
    @Override
        public void updateUser(User user, String password) {
            User currentUser = getUserFromSession();
            currentUser.setFirstName(user.getFirstName());
            currentUser.setLastName(user.getLastName());
            currentUser.setTwitterAccountName(user.getTwitterAccountName());
            if (password != null) {
                currentUser.updatePassword(password, user.getPassword(), user.getPassword());
            }
            userRepository.save(currentUser);
        }
    The user parameter if a User object created from a form submission, so detached. But the currentUser is the user in Spring Security SecurityContext. So I pass the values from the from submission to that currentUser object, then pass that to the userRepository.save method. But when I re-retrieve the user from the db, any changes are no longer there. Meaning it wasn't persisted to the db. The Transaction commits, no RuntimeExceptions to cause it to roll back.

    Or I could first go to the db reload the User, update that object and let the tx commit if I have to.

    Thanks

    Mark
    Last edited by bytor99999; Feb 23rd, 2012 at 12:02 PM.

  2. #2
    Join Date
    Jan 2011
    Location
    Dresden, Germany
    Posts
    525

    Default

    How and where do you retrieve the user from the database?

    Is it the user-object that is passed in from the session? So does it have the field: @GraphId Long id ?

    Or if you have your user indexed (e.g. on login) do a findByLogin(String login) and then update this user object.

    Have you looked in the database itself?

  3. #3
    Join Date
    Jan 2009
    Location
    Huntington Beach, CA
    Posts
    718

    Default

    Yes I have saved User objects before, it is a Node, it is id'd. I have looked in the database itself, the call to save is not saving to the database. In terms of how or where I retrieved it shouldn't matter. It is a mapped domain object that I pass to a call to save() even if it was detached, the save call would still save it. At some point that User object was loaded through the findByLogin method when the user logs in. The User object looks identical to what you have in Cineasts, I copied and pasted.

    Thanks

    Mark

  4. #4
    Join Date
    Jan 2011
    Location
    Dresden, Germany
    Posts
    525

    Default

    Any way we could reproduce it in a small test-setup?

    I would love to look at that. Never had this issue before.

    Thanks

    Michael

  5. #5
    Join Date
    Jan 2009
    Location
    Huntington Beach, CA
    Posts
    718

    Default

    I can't recreate the Web environment in a test. I ran a test with using the Repository directly and although it is possible it was asserting against data in a cache rather than the db, a call to userRepository.save worked.

    Unfortunately, it is still not saving and I have no idea why not.

    Will try some more.

    Mark

  6. #6
    Join Date
    Jan 2009
    Location
    Huntington Beach, CA
    Posts
    718

    Default

    Man that was a tough one to figure out. Like I had said previously, I copied the Cineasts User object to be my User object in my application. Including the updatePassword method. I was calling that method to update the user password and it was throwing an exception because the old password. From the User in the session it was already encoded, so calling updatePassword(String oldPassword….

    oldPassword needed to be the password decoded, but I don't have the decoded String, I have the encoded String. I changed the updatePassword to just take one String the new password and encode it and set the password instance variable to the encoded String, and now it will get to the userRepository.save(user) call.

    So the reason why it wasn't saved to the DB was because userRepository.save(user) never got called, an exception was thrown before that line.

    Mark

  7. #7

    Default Problem with @Transactional using Spring Data Neo4J

    Hello,

    I started using SPRING + Neo4J + SPRING Data Neo4j(SDN) recently.
    I am facing many compatibility issues. Now I am using

    SPRING - 3.1.1 RELEASE
    Neo4j - 1.8.M05
    SpringNeo4j - 2.1.0.RC1

    With aspectj mode I am facing NotInTransactionException problem even-though the method involved was annotated with @Transactional.

    Caused by: org.neo4j.graphdb.NotInTransactionException
    at org.neo4j.kernel.impl.index.IndexConnectionBroker. acquireResourceConnection(IndexConnectionBroker.ja va:49)
    at org.neo4j.index.impl.lucene.LuceneIndex.getConnect ion(LuceneIndex.java:85)
    at org.neo4j.index.impl.lucene.LuceneIndex.add(Lucene Index.java:138)
    at org.springframework.data.neo4j.support.typereprese ntation.AbstractIndexingTypeRepresentationStrategy .addToTypesIndex(AbstractIndexingTypeRepresentatio nStrategy.java:94)
    at org.springframework.data.neo4j.support.typereprese ntation.AbstractIndexingTypeRepresentationStrategy .writeTypeTo(AbstractIndexingTypeRepresentationStr ategy.java:56)
    at org.springframework.data.neo4j.support.mapping.TRS TypeAliasAccessor.writeTypeTo(TRSTypeAliasAccessor .java:46)
    at org.springframework.data.neo4j.support.mapping.TRS TypeAliasAccessor.writeTypeTo(TRSTypeAliasAccessor .java:26)
    at org.springframework.data.convert.DefaultTypeMapper .writeType(DefaultTypeMapper.java:153)
    at org.springframework.data.convert.DefaultTypeMapper .writeType(DefaultTypeMapper.java:139)
    at org.springframework.data.neo4j.support.mapping.Neo 4jEntityConverterImpl.write(Neo4jEntityConverterIm pl.java:148)
    at org.springframework.data.neo4j.support.mapping.Neo 4jEntityPersister$CachedConverter.write(Neo4jEntit yPersister.java:177)
    at org.springframework.data.neo4j.support.mapping.Neo 4jEntityPersister.persist(Neo4jEntityPersister.jav a:239)
    at org.springframework.data.neo4j.support.mapping.Neo 4jEntityPersister.persist(Neo4jEntityPersister.jav a:228)
    at org.springframework.data.neo4j.support.Neo4jTempla te.save(Neo4jTemplate.java:291)
    at com.social.poc.domain.DatabaseHandler.createStuden t(DatabaseHandler.java:224)
    at com.social.poc.domain.Neo4JResearchTest.main(Neo4J ResearchTest.java:25)

    Here is the transaction beans configuration:
    <tx:annotation-driven mode="aspectj" transaction-manager="neo4jTransactionManager"/>

    <bean id="neo4jTransactionManager"
    class="org.springframework.transaction.jta.JtaTran sactionManager">
    <property name="userTransaction" ref="neo4jUserTransactionService" />
    <property name="transactionManager" ref="neo4jTransactionManagerService" />
    </bean>

    <bean id="neo4jTransactionManagerService"
    class="org.neo4j.kernel.impl.transaction.SpringTra nsactionManager">
    <constructor-arg ref="graphDatabaseService" />
    </bean>

    <bean id="neo4jUserTransactionService" class="org.neo4j.kernel.impl.transaction.UserTrans actionImpl">
    <constructor-arg ref="graphDatabaseService" />
    </bean>

    <bean id="graphDatabaseService" class="org.neo4j.kernel.HighlyAvailableGraphDataba se"
    destroy-method="shutdown">
    ......
    </bean>

    any guidance to overcome the issue is appreciated.

    Regards
    Sampath

    Quote Originally Posted by bytor99999 View Post
    Man that was a tough one to figure out. Like I had said previously, I copied the Cineasts User object to be my User object in my application. Including the updatePassword method. I was calling that method to update the user password and it was throwing an exception because the old password. From the User in the session it was already encoded, so calling updatePassword(String oldPassword….

    oldPassword needed to be the password decoded, but I don't have the decoded String, I have the encoded String. I changed the updatePassword to just take one String the new password and encode it and set the password instance variable to the encoded String, and now it will get to the userRepository.save(user) call.

    So the reason why it wasn't saved to the DB was because userRepository.save(user) never got called, an exception was thrown before that line.

    Mark

  8. #8
    Join Date
    May 2012
    Posts
    107

    Default

    Sampath,

    Your code in Neo4JResearchTest.main, did you remember to obtain DatabaseHandler as a bean? Otherwise the @Transactional annotation will not trigger.

    Code ought to look like this:

    Code:
        public static void main( String[] args ) {
            FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext( "classpath:context.xml" );
            try {
                DatabaseHandler databaseHandler = ctx.getBean( DatabaseHandler.class );
    
                databaseHandler.createStudent();
            }
            finally {
                ctx.close();
            }
        }
    Also, for the Spring config, you might be able to simplyfy it: http://static.springsource.org/sprin.../html/#d0e3520

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •