Announcement Announcement Module
Collapse
No announcement yet.
NPE on @PostConstruct method that adds data to Neo4j with the Template Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • NPE on @PostConstruct method that adds data to Neo4j with the Template

    Not sure why I am getting these NPE. The code is in a method annotated with @PostConstruct, so maybe something hasn't been loaded yet?

    I am using the exact same Spring configuration files that I use in my integration tests and the same code to add new data that I use in the tests, and the tests run successfully.

    Here is the stack trace

    Code:
    Caused by: java.lang.NullPointerException
    	at org.springframework.data.neo4j.aspects.support.node.Neo4jNodeBacking.ajc$interMethod$org_springframework_data_neo4j_aspects_support_node_Neo4jNodeBacking$org_springframework_data_neo4j_aspects_core_NodeBacked$persist(Neo4jNodeBacking.aj:133)
    	at com.perfectworldprogramming.eventgate.user.User.persist(User.java:1)
    	at com.perfectworldprogramming.eventgate.user.User.persist(User.java:1)
    	at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:225)
    	at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:295)
    	at com.perfectworldprogramming.eventgate.user.TemporaryData.addNewData(TemporaryData.java:40)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:299)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:132)
    	... 22 more
    Here is my spring config file

    <neo4j:config storeDirectory="${neo4j.location}"/>
    <neo4j:repositories base-package="com.perfectworldprogramming.eventgate"/>
    <tx:annotation-driven mode="proxy"/>

    the value of neo4j.location is

    neo4j.location=db/eventgate.db

    Any guesses?

    Thanks

    Mark

  • #2
    Hey Mark,

    Can you show your test code and where this method TemporaryData.addNewData is called?

    Michael

    Comment


    • #3
      Now I am not getting a NPE, but an error stating that it can't set a primitive to null. However, any primitive types in my User class is defaulted to true, they are those Spring Security properties needed in a User class like credentialsNonExpired = true;
      enabled = true;

      Here is the TemporaryData class. The big thing here is @PostConstruct. With it I get the exceptions, first was the NPE, now IllegalArgumentException. Without @PostConstruct and calling the method directly things work without exceptions. So Something isn't setup completely when the @PostConstruct gets called by the CommonAnnotationsBeanPostProcessor. Is there any dynamic runtime introductions that can't happen till after the App Context is created???

      Code:
      @Service
      public class TemporaryData {
      
          @Autowired
          UserRepository userRepository;
      
          @Autowired
          EventRepository eventRepository;
      
          @Autowired
          ItemRepository itemRepository;
      
          // Fails with @PostConstruct
          @PostConstruct
          public void addNewData() {
      
              System.out.println("****** CREATING SAMPLE DATA ******");
              User aUser = userRepository.save(new User("auser", "password", "John", "Doe"));
              User bUser = userRepository.save(new User("buser", "password", "Mike", "Smith"));
              User cUser = userRepository.save(new User("cuser", "password", "Tom", "Smith"));
              Item coke6 = itemRepository.save(new Item("1234123412341234", "Coke 6 pack"));
              Item coke12 = itemRepository.save(new Item("1234123412341235", "Coke 12 pack"));
              Item coke1 = itemRepository.save(new Item("1234123412341236", "Coke Single"));
              Item dietCoke = itemRepository.save(new Item("1234123412341237", "Diet Coke"));
              Item pepsi = itemRepository.save(new Item("1234123412341234", "Pepsi 6-pack"));
              Item drPepper = itemRepository.save(new Item("1234123412341234", "Dr Pepper 6pack"));
              Item Rum = itemRepository.save(new Item("1234123412341234", "Rum"));
              Event game1 = eventRepository.save(new Event(new Date(), "USC Game", "Game Day at the coliseum"));
              Event game2 = eventRepository.save(new Event(new Date(), "Raiders", "Raiders game in Oakland"));
              Event game3 = eventRepository.save(new Event(new Date(), "USC Game2", "Another USC Game"));
              Event game4 = eventRepository.save(new Event(new Date(), "USC Game3", "Against Rival UCLA"));
              Event game5 = eventRepository.save(new Event(new Date(), "USC Game4", "SEC cant play"));
      
          }
      }
      Just caused you asked here is some of my Test code. But It isn't here that is the issue. Just tests to pinpoint that it is all about @PostConstruct here.

      Code:
      @ContextConfiguration({"classpath:META-INF/spring/applicationContext.xml",
              "classpath:META-INF/spring/applicationContext-graph.xml"})
      @RunWith(SpringJUnit4ClassRunner.class)
      public class UserDBTests {
          @Autowired
          Neo4jTemplate template;
      
          @Autowired
          UserRepository userRepository;
          
          @Autowired
          ApplicationContext context;
      
          @Autowired
          TemporaryData temporaryData;
      
          @Test
          @Transactional
          public void testTemporaryData() {
              temporaryData.addNewData();
          }
      
          @Test
          @Transactional
          public void persistedItemShouldBeRetrievableFromGraphDb() {
              User aUser = template.save(new User("auser", "password", "John", "Doe"));
              User retrievedUser = template.findOne(aUser.getId(), User.class);
              assertEquals("retrieved user matches persisted one", aUser, retrievedUser);
              assertEquals("retrieved user First Name matches", "John", retrievedUser.getFirstName());
              assertEquals("retrieved user last name matches", "Doe", retrievedUser.getLastName());
              assertEquals("retrieved user password matches", "password", retrievedUser.getPassword());
      
              retrievedUser = userRepository.findByPropertyValue("username", "auser");
      
              assertEquals("retrieved item matches persisted one", aUser, retrievedUser);
              assertEquals("retrieved user First Name matches", "John", retrievedUser.getFirstName());
              assertEquals("retrieved user last name matches", "Doe", retrievedUser.getLastName());
              assertEquals("retrieved user password matches", "password", retrievedUser.getPassword());
          }
      }
      Thanks for you help Michael

      Mark

      Comment


      • #4
        It seems you would have to add a "depends-on" in your TemporaryData probably on neo4jNodeBacking

        HTH

        Michael

        Comment


        • #5
          Originally posted by MichaelHunger View Post
          It seems you would have to add a "depends-on" in your TemporaryData probably on neo4jNodeBacking

          HTH

          Michael
          Thanks, I can use the @DependsOn annotation.

          Mark

          Comment


          • #6
            Don't have a neo4jNodeBacking bean as a BeanDefinition. This is what prints when I get the String[] of bean definition names.

            removing authorities interface org.springframework.security.core.GrantedAuthority interface org.springframework.security.core.GrantedAuthority
            removing authorities interface org.springframework.security.core.GrantedAuthority interface org.springframework.security.core.GrantedAuthority
            org.springframework.beans.factory.config.PropertyP laceholderConfigurer#0
            org.springframework.context.config.internalBeanCon figurerAspect
            temporaryData
            userServiceImpl
            org.springframework.context.annotation.internalCon figurationAnnotationProcessor
            org.springframework.context.annotation.internalAut owiredAnnotationProcessor
            org.springframework.context.annotation.internalReq uiredAnnotationProcessor
            org.springframework.context.annotation.internalCom monAnnotationProcessor
            org.springframework.context.annotation.internalPer sistenceAnnotationProcessor
            graphDatabaseService
            org.springframework.context.annotation.Configurati onClassPostProcessor#0
            org.springframework.data.neo4j.config.Neo4jConfigu ration#0
            userRepository
            itemRepository
            eventRepository
            org.springframework.data.repository.core.support.R epositoryInterfaceAwareBeanPostProcessor#0
            org.springframework.aop.config.internalAutoProxyCr eator
            org.springframework.transaction.annotation.Annotat ionTransactionAttributeSource#0
            org.springframework.transaction.interceptor.Transa ctionInterceptor#0
            org.springframework.transaction.config.internalTra nsactionAdvisor
            org.springframework.context.annotation.Configurati onClassPostProcessor$ImportAwareBeanPostProcessor# 0
            graphDatabase
            nodeTypeRepresentationStrategy
            neo4jTemplate
            mappingInfrastructure
            relationshipTypeRepresentationStrategy
            typeRepresentationStrategyFactory
            entityStateHandler
            nodeTypeMapper
            relationshipTypeMapper
            entityFetchHandler
            nodeStateTransmitter
            neo4jConversionService
            graphRelationshipInstantiator
            graphEntityInstantiator
            mappingContext
            relationshipEntityStateFactory
            nodeEntityStateFactory
            nodeDelegatingFieldAccessorFactory
            relationshipDelegatingFieldAccessorFactory
            neo4jTransactionManager
            configurationCheck
            persistenceExceptionTranslator
            indexProvider
            org.springframework.context.annotation.Configurati onClassPostProcessor$ImportAwareBeanPostProcessor# 1

            Which one should it depend on?

            Thanks

            Mark

            Comment


            • #7
              OK, I have resolved my issue, I get the @PostConstruct method to run successfully without any @DependsOn.

              Here was my issue. My Node object is my User, which is also used for Spring Security, so therefore my UserDetails object. In Spring Security UserDetails object you must have is methods for 4 booleans, isEnabled() etc. However, I made them actual attributes of my User class like boolean enabled;. This is where the problem occurs, The Domain object annotated as a NodeEntity, like JPA makes all attributes/fields of a class to be persistent. Which made my 4 UserDetails boolean fields persistent, but they are primitive booleans. So by not making them instance variables and just "is" methods returning true, since I don't need to save that stuff, it works.

              Now I just have to do the same for GrantedAuthority objects as they are automatically being ignored, so I have to save it as a String array then have code to convert then to GrantedAuthority.

              Michael has done all this in the Cineasts example project, it is an elegant solution and one that takes a little bit to fully understand but is the best solution to the problem of using a Node as also your Spring Security UserDetails object.

              Funny thing, is I also will end up allowing OAuth with Facebook etc for people to login, and will have a simple User object for those without storing security info in the database for those Users.

              Thanks

              Mark

              Comment


              • #8
                It is still odd that this issue occurs in a @PostConstruct versus later after the ApplicationContext if fully populated.

                I never posted the last exception I got, and might shed some more light. The BeanWrapper class and GenericConversionService is where I was concentrating my focus, didn't help me focus, but I did focus there.

                Code:
                Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'temporaryData': Invocation of init method failed; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type null to type boolean for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
                	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:135)
                	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
                	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1448)
                	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
                	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:585)
                	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
                	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
                	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
                	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
                	at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
                	at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
                	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
                	... 27 more
                Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type null to type boolean for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
                	at org.springframework.core.convert.support.GenericConversionService.assertNotPrimitiveTargetType(GenericConversionService.java:487)
                	at org.springframework.core.convert.support.GenericConversionService.handleResult(GenericConversionService.java:481)
                	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:163)
                	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:154)
                	at org.springframework.data.mapping.model.BeanWrapper.getPotentiallyConvertedValue(BeanWrapper.java:233)
                	at org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:158)
                	at org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:140)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:101)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:111)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:39)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$1.doWithPersistentProperty(SourceStateTransmitter.java:57)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$1.doWithPersistentProperty(SourceStateTransmitter.java:54)
                	at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:173)
                	at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:54)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:98)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:90)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:168)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:186)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:239)
                	at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:227)
                	at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:295)
                	at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:106)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:322)
                	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:307)
                	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
                	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
                	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:202)
                	at $Proxy39.save(Unknown Source)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
                	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.invoke(TransactionInterceptor.java:110)
                	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
                	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
                	at $Proxy41.save(Unknown Source)
                	at com.perfectworldprogramming.eventgate.user.TemporaryData.addNewData(TemporaryData.java:36)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346)
                	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:299)
                	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:132)
                	... 43 more
                Caused by: java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
                	at org.springframework.core.convert.support.GenericConversionService.assertNotPrimitiveTargetType(GenericConversionService.java:488)
                	... 96 more
                Thanks

                Mark

                Comment


                • #9
                  OK, the @PostConstruct only works in my Junit Integration test and fails with the NPE when I deploy to Tomcat 7. So I guess I am back to my original problem. ;(

                  Mark

                  Comment


                  • #10
                    OK, now it does work on deploy to Tomcat 7. I chalk this one to Tomcat 7 still having an old version of my war expanded and not using the new .war file I added to webapps. So I made sure to delete it all then recopy my war to Tomcat and then start Tomcat and it worked.

                    Mark

                    Comment


                    • #11
                      What is your spring config?

                      Michael

                      Comment


                      • #12
                        Somehow weird b/c if you use the AJ approach (spring-data-neo4j-aspects), the must be a neo4jNodeBacking bean.

                        Comment


                        • #13
                          Originally posted by MichaelHunger View Post
                          What is your spring config?

                          Michael
                          applicationContext.xml

                          Code:
                          <?xml version="1.0" encoding="UTF-8" standalone="no"?>
                          <beans xmlns="http://www.springframework.org/schema/beans"
                                 xmlns:aop="http://www.springframework.org/schema/aop"
                                 xmlns:context="http://www.springframework.org/schema/context"
                                 xmlns:jee="http://www.springframework.org/schema/jee"
                                 xmlns:tx="http://www.springframework.org/schema/tx"
                                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                 xsi:schemaLocation="http://www.springframework.org/schema/aop
                                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                                     http://www.springframework.org/schema/beans
                                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                     http://www.springframework.org/schema/context
                                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                                     http://www.springframework.org/schema/jee
                                     http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
                                     http://www.springframework.org/schema/tx
                                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
                          
                              <context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
                          
                              <context:spring-configured/>
                          
                              <context:component-scan base-package="com.perfectworldprogramming.eventgate">
                                  <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
                              </context:component-scan>
                          
                          </beans>
                          applicationContext-graph.xml which was posted above before.

                          Code:
                          <?xml version="1.0" encoding="UTF-8" standalone="no"?>
                          <beans xmlns="http://www.springframework.org/schema/beans"
                                 xmlns:tx="http://www.springframework.org/schema/tx"
                                 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/tx
                                 http://www.springframework.org/schema/tx/spring-tx.xsd
                                 http://www.springframework.org/schema/data/neo4j
                                 http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">
                          
                          
                              <neo4j:config storeDirectory="${neo4j.location}"/>
                              <neo4j:repositories base-package="com.perfectworldprogramming.eventgate"/>
                              <tx:annotation-driven mode="proxy"/>
                          </beans>
                          My other config files are for Spring MVC components and Spring Security and they only include beans for the web layer and security layer, nothing Spring Data related.

                          I do not have neo4j-aspects in my pom file.

                          Thanks Michael

                          Mark

                          Comment

                          Working...
                          X