Announcement Announcement Module
Collapse
No announcement yet.
Issue with basic dependency injection. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Issue with basic dependency injection.

    Hi Guys,

    I have a scenario where I need to inject values to the Arraylist in a class that does not have the setter I believe in this scenario I need to do a get on the list in the POC class and then do a add:

    public class POC {

    private ArrayList<String> beheaviour=new ArrayList<String>();

    public ArrayList<String> getBeheaviour() {
    return beheaviour;
    }


    }
    Here is the xml mapping code :

    <bean id="poc" class="outBoundocument.factory.POC">
    <property name="beheaviour">
    <list>
    <value>temp1</value>
    <value>temp2</value>
    <value>temp3</value>
    <value> temp4</value>
    <value>temp5</value>
    </list>
    </property>
    </bean>

    the following code returns :

    Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'beheaviour' of bean class [outBoundocument.factory.POC]: Bean property 'beheaviour' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?


    Moreover there is no way for me to modify the POC class so I will have to perform a property Injection some how. The Java translation of the above is as simple as

    POC poc =new POC ();
    poc.getBeheaviour.add("crap")
    Last edited by swaroopanl; May 23rd, 2011, 03:07 PM. Reason: updated it to make more sense

  • #2
    You defined bean meta data in the context.xml as create a bean POC and inject a property named (behavior) with a setter injection, Hence you need to define a setter method in your POC class , To resolve the issue just add a setter method in your POC class


    public void setBeheaviour(List<String> beheaviour)
    {
    this.beheaviour = beheaviour;
    }

    Code:
    <bean id="poc" class="outBoundocument.factory.POC">
    <property name="beheaviour">
    <list>
    <value>temp1</value>
    <value>temp2</value>
    <value>temp3</value>
    <value> temp4</value>
    <value>temp5</value>
    </list>
    </property> 
    </bean>

    Comment


    • #3
      Hi Patalakanti,

      As I have mentioned in the post there is no way for me to change the POC class as this it is a vendor provided class.Just for example you would run in to this scenario when the classes are generated trough JAXB too.Thanks for the post but the answer is not that simple as you suggested unfortunately.

      Comment


      • #4
        Sorry I missed the part about not being able to change POC class, If I understand you'r requirements, You are trying to extend POC class that is belongs to a third party

        You can do some thing like this (It will not work if the POC has defesive copying for behavior property)

        Code:
        public class POCExtension 
        {
        	
        	private POC test;
        	
        	public POCExtension(List<String> behaviorList, POC pocBean)
        	{
        		this.test = pocBean;
        		this.test.getBeheaviour().addAll(behaviorList);
        	}
        
        	public POC getTest() {
        		return test;
        	}
        }
        and configure your POC in context.xml file

        Code:
        <bean class="spring.jpa.service.POCExtension">
        <constructor-arg name="behaviorList">
        <list>
          <value>one</value>
        </list>
        </constructor-arg>
        <constructor-arg name="pocBean" ref="test"/>
        </bean>
        This will change the state of POC class (what I am suggesting is essetially a hack)

        Comment


        • #5
          Hi
          Add a new class which extends your POC class and add a setter in the extended class. In your bean definition use this extended class. Hope this may solve your problem

          public class POC
          {
          private List<String> lists=new ArrayList<String>();

          public List<String> getLists() {
          return lists;
          }
          }


          public class POCExtended extends POC{

          public void setLists(List<String> lists) {
          getLists().addAll(lists);


          }
          }



          <bean id="POCBean" class="POCExtended">
          <property name="lists">
          <util:list list-class="java.util.ArrayList">
          <value>1</value>
          <value>2</value>
          <value>3</value>
          </util:list>
          </property>
          </bean>
          Last edited by vishnu.joshi; May 23rd, 2011, 05:18 PM.

          Comment


          • #6
            Or write a FactoryBean which does the complex stuff.

            Code:
            public class POCFactoryBean implements FactoryBean<POC> {
            
              private List<String> beheaviour=new ArrayList<String>();
            
              public void setBeheaviour(List<String> beheaviour) {
                this.beheaviour=beheaviour;
              }
            
              public POC getObject() {
                POC poc = new POC();
                poc.getBeheaviour().addAll(this.beheaviour);
                return poc;
              }
            
            }
            Hopefully the class isn't very well written and the getBeheaviour returns the internal representation of the list and not a copy or unmodifiable list (which is what I would do ). If that is the case you would need to use reflection to set the field value instead of using the getter and add.

            Comment


            • #7
              Or write a FactoryBean which does the complex stuff.

              Code:
              public class POCFactoryBean implements FactoryBean<POC> {
              
                private List<String> beheaviour=new ArrayList<String>();
              
                public void setBeheaviour(List<String> beheaviour) {
                  this.beheaviour=beheaviour;
                }
              
                public POC getObject() {
                  POC poc = new POC();
                  poc.getBeheaviour().addAll(this.beheaviour);
                  return poc;
                }
              
              }
              Hopefully the class isn't very well written and the getBeheaviour returns the internal representation of the list and not a copy or unmodifiable list (which is what I would do ). If that is the case you would need to use reflection to set the field value instead of using the getter and add.

              Comment


              • #8
                Thanks Guys for the response but unfortunately if I perform all these changes I don't have the behavior bean persisting the changes as this behavior bean finally needs to be marshalled as xml. I now understand that there is no easy way to do this unless I use Aspect4j.Thanks for pouring in your responses.

                Comment


                • #9
                  If the class/bean you are mentioning isn't spring managed (but instantiated by new or reflection) the changes as proposed are useless but that wasn't part of your initial question.

                  Comment


                  • #10
                    Hi Marten,

                    The solutions that were proposed by you, Patalakanti and Vishnu are perfectly valid but I have a scenario where I need to to create a factory implementation 230 times for various objects I get from the complex object factory.Hence I choose not to go in that direction as this would be a maintainence nightmare. But I respect your thoughts and solution that you guys proposed.Thanks for your time.

                    Comment


                    • #11
                      You can always revert to reflection and make it generic. Create a FactoryBean that takes a Map<String, Object> as parameters and a class as type to return. Then use reflection to set the field values based on the name and value on the map. That way you only have 1 bean to maintain, however it would still be a configuration nightmare.

                      Comment


                      • #12
                        I agree :-) Thanks Marten for your Ideas I hope spring source comes up with a easy solution to address this kind of issue.

                        Comment

                        Working...
                        X