Announcement Announcement Module
Collapse
No announcement yet.
property on bean overwritten with null Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • property on bean overwritten with null

    Hello.

    I am trying to get a reference to a FactoryBean I have defined inside my context.
    First approach:
    Code:
        
         <bean id="backupProxy" parent="txProxyTemplate" singleton="true">
            <property name="target">
                <ref local="backupTarget"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="backup*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="restore*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>
        
        <bean id="backupTarget" class="migration.backup.Backup" 
            singleton="true">
            <property name="batchSize">
                <value>50</value>
            </property>
            <property name="xstream" ref="xstream"/>
            <property name="factoryBean" ref="&amp;HBSessionFactory"/>
        </bean>
    I have checked inside backupTarget and the factoryBean property is null (I assume because there are some circular dependencies - as txProxyTemplate depends on HBSessionFactory).

    I have used the programatic approach - I have a servlet context listener which at the application startup retrieves the backupTarget and sets the appropriate property.

    Second approach:
    Code:
            LocalSessionFactoryBean factoryBean = &#40;LocalSessionFactoryBean&#41; appContext.getBean&#40;"&HBSessionFactory"&#41;;
            Backup backup = &#40;Backup&#41;appContext.getBean&#40;"backupTarget"&#41;;
    
            if &#40;log.isDebugEnabled&#40;&#41;&#41;
            &#123;
                log.debug&#40;"factoryBean is " + factoryBean&#41;;
                log.debug&#40;"backup is " + backup&#41;;
            &#125;
            
            backup.setHbFactoryBean&#40;factoryBean&#41;;
            log.info&#40;"checking the factory bean" + &#40;&#40;Backup&#41;appContext.getBean&#40;"backupTarget"&#41;&#41;.getHbFactoryBean&#40;&#41;&#41;;
    I have placed logging also inside Backup class and I can see that the beanFactory I get is NOT null and the setter on backupTarget is called correctly.
    However, when methods inside backupTarget are called (through BackupProxy) even though the logging clearly shows that it's the same backup instance used before the factoryBean property is null!
    I double checked the configuration and it's the same instance and the setter is not called except by me with a value different then null.

    I have tried also using directly backupProxy with the same effect - why does my property gets re-written with a null?

    I am using Spring 1.2 - any ideas, hints? It seems that somewhere things go wrong by I can't find where.

  • #2
    I have made the property static and it's no longer null - it seems that Spring somehow recreated the object; however the singleton flag is set to true and also the signature of the object (hashcode) is the same.
    What's going on?

    Comment


    • #3
      Do you work with multiple threads?
      If yes, that could be an explanation if correct synchronization of the property accessors is missing, for each thread keeps its own memory which might not be in sync in your case.

      Regards,
      Andreas

      Comment


      • #4
        I'm not working with multiple threads - I am just loading the Spring context inside Tomcat and then call the method through the web by making an http request.
        However, even if some threading issue occurs, why does the object which contains the null property (which is not suppose to be null) - is not different - the propety is not threadlocal or anything?
        And how can I synchronize or solve this problem?

        Comment


        • #5
          Originally posted by costin
          However, even if some threading issue occurs, why does the object which contains the null property (which is not suppose to be null) - is not different - the propety is not threadlocal or anything?
          Each thread has its own memory area. So even if the object is the same, the property references local to the thread might differ. If you set a property, you do this in the current threads local memory area. The change might not be reflected in the main memory immediately. That is why a different thread might have a stale view of the object. Synchronization of the thread memory with the main memory can be enforced by entering a synchronized block.

          Originally posted by costin
          And how can I synchronize or solve this problem?
          The simplest method would be to synchronize all methods which access the property (reading or writing). Just add the "synchronized" keyword to the according methods.

          Regards,
          Andreas

          Comment


          • #6
            I am also having a similar issue and I believe that I have isolated it to be a problem with the hash map for the beans. When I changed the bean id it seems to have helped, but it did not solve the problem completely. Is there a way to change the hash map configurations for the beans in order to prevent hash collisions and therefore overwriting?

            Comment


            • #7
              Originally posted by durcekp
              I am also having a similar issue and I believe that I have isolated it to be a problem with the hash map for the beans. When I changed the bean id it seems to have helped, but it did not solve the problem completely. Is there a way to change the hash map configurations for the beans in order to prevent hash collisions and therefore overwriting?
              I do not think that hashing has something to do with this issue. BTW: are you referring to a HashMap used by spring internally to hold the beans?

              As for hash collisions: A collision of hash values does not imply any overwriting. Only if an existing entry equals a new one, the old one gets replaced.
              If two objects are equal, they should have the same hach-code. But two objects with the same hash-code do not need to be equal.

              Regards,
              Andreas

              Comment


              • #8
                I was refering to the HashMap used by spring internally to hold the beans. I have posted more on this in the following topic:

                java.lang.ClassCastException: $Proxy1
                http://forum.springframework.org/showthread.php?t=15325

                If the bean objects were identical they would be the same class and therefore the same object. However, since the ones I am dealing with are 3 different classes with completelly different definitions they should not be overwriten in the HashMap. The problem gets resolved if I remove one (does not matter which one) of the bean mappings from the applicationContext file.

                I am not specifying any bean storage parameters explicitly and am puzzled why the problem occurs.

                - Paul
                Last edited by robyn; May 14th, 2006, 10:59 AM.

                Comment


                • #9
                  I will try the synchronized solution today but I doubt is going to work. Concurrency/synchornization problems appear when several threads are running in parallel - here the listener loads the bean at when the app is deployed; the request comes several minutes later.

                  Comment

                  Working...
                  X