-
1. Re: Injection And Child Objects
jimk1723 Feb 25, 2008 8:17 PM (in response to tom_goring)Using your example I got the following exception:
org.jboss.seam.RequiredException: @In attribute requires non-null value: parent.dependency at org.jboss.seam.Component.getValueToInject(Component.java:2160)
Which is what I expected. Have you tried using:
@In(create = true) Dependency dependency;
A more fringe explanation: do you have a name collision anywhere with the
parent
component, i.e. are you referencing the component you think you're referencing? -
2. Re: Injection And Child Objects
danielc.roth Feb 25, 2008 8:18 PM (in response to tom_goring)I'm a bit confused over what you're trying to do. 'dependency' will always be null if you haven't outjected it before. Have you done that?
private child = null;
seems a bit weird. Untyped? -
3. Re: Injection And Child Objects
keithnaas Feb 25, 2008 8:19 PM (in response to tom_goring)What version of Seam are you using?
Also, can you provide the code for the Dependency object since that could likely be the issue.
-
4. Re: Injection And Child Objects
tom_goring Feb 25, 2008 8:27 PM (in response to tom_goring)The simple code was just for illustration (i.e. Child typo)
I'm using jboss-seam-2.0.1.CR1.
dependency already existed.
I'll post a real example then if people think it should work.
So having a EL expression with a child object injection should happen to every object that is a seam object in that expression ?
-
5. Re: Injection And Child Objects
jimk1723 Feb 25, 2008 10:09 PM (in response to tom_goring)
I'll post a real example then if people think it should work.Yah. We're missing some crucial details here.
So having a EL expression with a child object injection should happen to every object that is a seam object in that expression ?The question is oddly worded, but the Seam reference covers this pretty well:
dynamic - since the value of contextual variables changes over time, and since Seam components are stateful, bijection takes place every time a component is invoked -
6. Re: Injection And Child Objects
tom_goring Feb 25, 2008 11:36 PM (in response to tom_goring)Hi,
Here Goes then ....
@Name("seamDependency") public class SeamDependency { }
@Name("seamParent") public class SeamParent { @In(create=true) SeamDependency seamDependency; PojoChild pojoChild; public String property; public SeamParent() { pojoChild = new PojoChild(this); } public String getProperty() { System.out.println("SeamParent.getProperty = "+this+"="+seamDependency); return property; } public void setProperty(String property) { this.property = property; } public PojoChild getPojoChild() { return pojoChild; } public void setPojoChild(PojoChild pojoChild) { this.pojoChild = pojoChild; } }
public class PojoChild { public SeamParent parent; public String property; public PojoChild(SeamParent parent) { this.parent = parent; } public String getProperty() { System.out.println("PojoChild.getProperty = "+parent+"="+parent.seamDependency); return property; } public void setProperty(String property) { this.property = property; } }
My Page
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:jnet="http://jnet.ltd.uk/taglib" xmlns:s="http://jboss.com/products/seam/taglib"> <body> <h:form> <h:inputText value="#{seamParent.pojoChild.property}"></h:inputText> <h:inputText value="#{seamParent.property}"></h:inputText> </h:form> </body> </html>
Console Output during a HTTP get
22:26:27,036 INFO [STDOUT] PojoChild.getProperty = jnet.fui.bl.util.SeamParent@15fcabc=null 22:26:27,037 INFO [STDOUT] SeamParent.getProperty = jnet.fui.bl.util.SeamParent@15fcabc=jnet.fui.bl.util.SeamDependency@1f72039
I.e. you can see injection does not occur when the child property is referenced
-
7. Re: Injection And Child Objects
pmuir Feb 25, 2008 11:45 PM (in response to tom_goring)No, this ain't going to work. this isn't a valid reference to the Seam component parent - it's just a reference to the POJO parent.
Try
@Create public void create() this.pojoChild = new PojoChild(instance()); } public static SeamParent instance() { return Component.getInstance("seamParent"); }
-
8. Re: Injection And Child Objects
tom_goring Feb 26, 2008 12:09 AM (in response to tom_goring)Hi Pete,
Nope that does not work.
@Name("seamParent") public class SeamParent { @In(create=true) SeamDependency seamDependency; PojoChild pojoChild; public String property; public SeamParent() { } public String getProperty() { System.out.println("SeamParent.getProperty = "+this+"="+seamDependency); return property; } public void setProperty(String property) { this.property = property; } public PojoChild getPojoChild() { return pojoChild; } public void setPojoChild(PojoChild pojoChild) { this.pojoChild = pojoChild; } @Create public void create() { this.pojoChild = new PojoChild(instance()); } public static SeamParent instance() { return (SeamParent)Component.getInstance("seamParent"); } }
[STDOUT] PojoChild.getProperty = jnet.fui.bl.util.SeamParent@df43b7=null [STDOUT] SeamParent.getProperty = jnet.fui.bl.util.SeamParent@df43b7=jnet.fui.bl.util.SeamDependency@1ddae12
-
9. Re: Injection And Child Objects
pmuir Feb 26, 2008 12:30 AM (in response to tom_goring)Hmm. I guess the instantiation isn't complete by that point - file a feature request in JIRA - what you are trying to do seems reasonable - but we need to consider it carefully.
As a workaround, can you lazily create the pojoChild in the getter (by which point your component will be fully instatiated)?
-
10. Re: Injection And Child Objects
tom_goring Feb 26, 2008 1:08 AM (in response to tom_goring)Hi Pete,
Nope that does not work for me,...
@Name("seamParent") public class SeamParent { @In(create=true) SeamDependency seamDependency; PojoChild pojoChild; public String property; public SeamParent() { } public String getProperty() { System.out.println("SeamParent.getProperty = "+this+"="+seamDependency); return property; } public void setProperty(String property) { this.property = property; } public PojoChild getPojoChild() { if ( pojoChild==null ) { System.out.println("creating pojo"); this.pojoChild = new PojoChild(instance()); } return pojoChild; } public void setPojoChild(PojoChild pojoChild) { this.pojoChild = pojoChild; } @Create public void create() { } public static SeamParent instance() { return (SeamParent)Component.getInstance("seamParent"); } }
[LifeCycleListener] BeforePhase: RENDER_RESPONSE 6 [STDOUT] creating pojo [STDOUT] PojoChild.getProperty = jnet.fui.bl.util.SeamParent@1bdcd96=null [STDOUT] SeamParent.getProperty = jnet.fui.bl.util.SeamParent@1bdcd96=jnet.fui.bl.util.SeamDependency@4473c [LifeCycleListener] AfterPhase: RENDER_RESPONSE 6
It looks to me that during the EL expression resolution I would expect the injection to occur but it does not when you reference a child property....
-
11. Re: Injection And Child Objects
tom_goring Feb 26, 2008 3:30 PM (in response to tom_goring)Added JIRA
http://jira.jboss.org/jira/browse/JBSEAM-2677
Workaround is to rather than store the parent reference in the PojoChild look it up every time it is required.
PojoChild in my case is like a utility class that can add functionality to the parent... Doing the look up or using injection makes the utility more cumbersome as it does not know the parent seam component name at runtime (and so this would have to be passed in). -
12. Re: Injection And Child Objects
matt.drees Feb 27, 2008 1:37 AM (in response to tom_goring)
Tom Goring wrote on Feb 25, 2008 11:36 PM:@Name("seamParent") public class SeamParent { @In(create=true) SeamDependency seamDependency; ... }
public class PojoChild { public SeamParent parent; ... public String getProperty() { System.out.println("PojoChild.getProperty = "+parent+"="+parent.seamDependency); return property; } ... }
I think your problem is you're directly referencing the parent's field. Injection is only going to occur if you call a method, e.g.,
... parent.getSeamDepency()
The reason is the SeamParent object that child has a reference to is a proxy, and its fields aren't ever used.
-
13. Re: Injection And Child Objects
tom_goring Feb 27, 2008 9:20 AM (in response to tom_goring)Hi,
Nope that does not work... I would be helpful if a Seam Expert could explain on what condition injection occurs (e.g. looking up a component in a context).
Code Changed to:
@Name("seamParent") public class SeamParent { ... public SeamDependency getSeamDependency() { System.out.println("SeamParent.getSeamDependency Accessor Called "+seamDependency); return seamDependency; } ...
And :
public class PojoChild { ... public String getProperty() { System.out.println("PojoChild.getProperty = "+parent+"="+parent.getSeamDependency()); return property; } ... }
Output is:
[STDOUT] creating pojo [STDOUT] SeamParent.getSeamDependency Accessor Called null [STDOUT] PojoChild.getProperty = jnet.fui.bl.util.SeamParent@1ccb4e6=null [STDOUT] SeamParent.getProperty = jnet.fui.bl.util.SeamParent@1ccb4e6=jnet.fui.bl.util.SeamDependency@786e17
-
14. Re: Injection And Child Objects
mars1412 Feb 27, 2008 3:04 PM (in response to tom_goring)according to petes suggestion, did you use SeamParent.instance() on your child?
public String getProperty() { System.out.println("PojoChild.getProperty = "+parent+"="+SeamParent.instance().seamDependency); return property; }