Skip to main content
Announcements
A fresh, new look for the Data Integration & Quality forums and navigation! Read more about what's changed.
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

Passing a Map or List object back to Parent Job via tBufferOutput bug?

I am able to pass a Map object down from a parent to a child via context variables without any problems. However, when I attempt to pass a Map object back up to the parent via a tBufferOutput, I am unable to cast it to a Map in the parent without getting a java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map error.
For example, I have two jobs, ParentMap and ChildMap, to illustrate this. Both jobs have a context variable "map" of type "Object".
The parent Object consists of tJava --onComponentOk-->tRunJob(ChildMap--row1(main)-->tJavaRow.
0683p000009MElS.pngIn the tJava, I create a HashMap, put two entries in it, and set context.map to the HashMap.
In the ChildMap, I set the context parameter map to the ParentMap's context.map:
0683p000009MErU.png
The ChildMap job consists of tJava--row1(main)-->tBufferOutput.

0683p000009MEgi.pngAs you can see, I am able to cast the context.map object (that was passed from the parent via context variables) into a HashMap. I also set row1.map to this context.map and pass it to the tBufferOutput, which has a variable "map" of type "Object".
Now, back to the parent, I have the following code in the tJavaRow that attempts to cast the map object into a hashmap and iterate over it.
0683p000009MErZ.png
However, the job fails in the parent when I run it:

0683p000009MEre.png
I have an identical ParentList/ChildList jobs which show the same behavior for Lists:

0683p000009MErj.png
So it appears that Talend is calling the toString() method on any "Object" in the tBufferOutput, thus rendering it a String and not a polymorphic Object. Is this behavior intentional and I am misunderstanding how I should be passing complex Objects from a child job back to a parent job, or is this a bug?
How should I go about passing a List or Map or other complex Object back up to the parent job from a child job?
Regards,
Matthew
Labels (3)
4 Replies
Anonymous
Not applicable
Author

Hi Matthew,
What is the datatype of context.map in child? 
You need not use tBuffer component for this task in child. You can simply assign value in child to context variable and in parent call that value again... during this you will have to enable checkbox, transmit all context. One more thing is you will have to have this context in both the jobs with same datatype.
You can also think of using getter-setter routines for this purpose.
Thanks
Vaibhav
Anonymous
Not applicable
Author

Hi Matthew,
What is the datatype of context.map in child? 
You need not use tBuffer component for this task in child. You can simply assign value in child to context variable and in parent call that value again... during this you will have to enable checkbox, transmit all context. One more thing is you will have to have this context in both the jobs with same datatype.
You can also think of using getter-setter routines for this purpose.
Thanks
Vaibhav

Hi Vaibhav.
The datatype was the same in parent and child. I did what you suggested and you were right with regards to the Map and the List as the object datatype.
However, this odd result happens when I use the Long data type. I have the same setup, a Parent and Child job. They both have the same context variable name and data type (name is "obj" type is "Long").
0683p000009MEmQ.png
In the Child job, I have a tJava that sets the context variable to a Long:

0683p000009MEro.png
And back in the parent, the tJava will try to print the value of context.obj:

0683p000009MEqm.png
However, when I run the job:

0683p000009MErt.png
I have tried setting both the parent and child's "obj" datatype to "Object" but had the same result.

This leads me to understand that passing a context variable to a subjob is the same as passing a variable as an argument to a method in java-- if the object is immutable (like Long), then it won't be changed inside; if it isn't immutable (like Map/List), then it will be changed inside.
If this is the case, then how may we change the context variable inside of a subjob for immutable objects?

Thank you,
Matthew
Anonymous
Not applicable
Author

Not sure, what is the problem, but usually i do it using routines (getter-setter) to transmit values from child job to parent job and use context variables when transmitting from parent to child jobs.
Vabhav
_AnonymousUser
Specialist III

I am able to pass a Map object down from a parent to a child via context variables without any problems. However, when I attempt to pass a Map object back up to the parent via a tBufferOutput, I am unable to cast it to a Map in the parent without getting a java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map error.
For example, I have two jobs, ParentMap and ChildMap, to illustrate this. Both jobs have a context variable "map" of type "Object".
The parent Object consists of tJava --onComponentOk-->tRunJob(ChildMap--row1(main)-->tJavaRow.
172438/mini_blob_20140907-0315.png
In the tJava, I create a HashMap, put two entries in it, and set context.map to the HashMap.
In the ChildMap, I set the context parameter map to the ParentMap's context.map:
172438/mini_blob_20140907-0317.png
The ChildMap job consists of tJava--row1(main)-->tBufferOutput.

172438/mini_blob_20140907-0320.png
As you can see, I am able to cast the context.map object (that was passed from the parent via context variables) into a HashMap. I also set row1.map to this context.map and pass it to the tBufferOutput, which has a variable "map" of type "Object".
Now, back to the parent, I have the following code in the tJavaRow that attempts to cast the map object into a hashmap and iterate over it.
172438/mini_blob_20140907-0322.png
However, the job fails in the parent when I run it:

172438/mini_blob_20140907-0324.png
I have an identical ParentList/ChildList jobs which show the same behavior for Lists:

172438/mini_blob_20140907-0332.png
So it appears that Talend is calling the toString() method on any "Object" in the tBufferOutput, thus rendering it a String and not a polymorphic Object. Is this behavior intentional and I am misunderstanding how I should be passing complex Objects from a child job back to a parent job, or is this a bug?
How should I go about passing a List or Map or other complex Object back up to the parent job from a child job?
Regards,
Matthew

Hi Matthew,
I found the same exception and fixed it by following way:
Please check it once and let me know if it not works for you.
https://community.talend.com/t5/Design-and-Development/resolved-tBufferOutput-java-util-HashMap-cann...

Thanks
Sayagoud Ravelly.