Details
-
Type: Improvement
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: EE-2.0.0.GA
-
Fix Version/s: 2.1-Beta, EE-2.0.0.GA_P01
-
Component/s: ICE-Components
-
Labels:None
-
Environment:-
-
Assignee Priority:P1
Description
Consider the following source code (BeanA and BeanB source is the same):
@SessionScoped
public class BeanA implements Serializable
{
@PostConstruct
public void init(){
System.out.println("A Created ");
}
public List<String> getA(){
return Arrays.asList("A", "A");
}
}
and the view:
<ice:panelTabSet>
<ice:panelTab label="1">
</ice:panelTab>
<ice:panelTab label="2">
<ice:dataTable value="#{beanB.b}" var="_b">
<ice:column>
<ice:outputText value="#{_b}" />
</ice:column>
</ice:dataTable>
</ice:panelTab>
<ice:panelTab label="3">
<ice:dataTable value="#{beanA.a}" var="_a">
<ice:column>
<ice:outputText value="#{_a}" />
</ice:column>
</ice:dataTable>
</ice:panelTab>
</ice:panelTabSet>
If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc..
@SessionScoped
public class BeanA implements Serializable
{
@PostConstruct
public void init(){
System.out.println("A Created ");
}
public List<String> getA(){
return Arrays.asList("A", "A");
}
}
and the view:
<ice:panelTabSet>
<ice:panelTab label="1">
</ice:panelTab>
<ice:panelTab label="2">
<ice:dataTable value="#{beanB.b}" var="_b">
<ice:column>
<ice:outputText value="#{_b}" />
</ice:column>
</ice:dataTable>
</ice:panelTab>
<ice:panelTab label="3">
<ice:dataTable value="#{beanA.a}" var="_a">
<ice:column>
<ice:outputText value="#{_a}" />
</ice:column>
</ice:dataTable>
</ice:panelTab>
</ice:panelTabSet>
If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc..
Issue Links
- is duplicated by
-
ICE-7314 Backing bean called on children of non-rendered elements
- Closed
Activity
Tyler Johnson
created issue -
Tyler Johnson
made changes -
Field | Original Value | New Value |
---|---|---|
Salesforce Case | [5007000000I1Ht3] | |
Description |
Consider the following source code: @SessionScoped public class A implements Serializable { @PostConstruct public void init() { System.out.println("A Created "); } public List<String> getA() { return Arrays.asList("A", "A"); } } and a second bean: @SessionScoped public class B implements Serializable { @PostConstruct public void init() { System.out.println("B Created "); } public List<String> getB() { return Arrays.asList("B", "B"); } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <h:dataTable value="#{b}" var="_b"> <h:column> <ice:outputText value="#{_b}"/> </h:column> </h:dataTable> </ice:panelTab> <ice:panelTab label="3"> <h:dataTable value="#{a}" var="_a"> <h:column> <ice:outputText value="#{_a}"/> </h:column> </h:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Consider the following source code: @SessionScoped public class A implements Serializable{ @PostConstruct public void init(){ System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } } and a second bean: @SessionScoped public class B implements Serializable{ @PostConstruct public void init(){ System.out.println("B Created "); } public List<String> getB(){ return Arrays.asList("B", "B"); } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <h:dataTable value="#{b}" var="_b"> <h:column> <ice:outputText value="#{_b}"/> </h:column> </h:dataTable> </ice:panelTab> <ice:panelTab label="3"> <h:dataTable value="#{a}" var="_a"> <h:column> <ice:outputText value="#{_a}"/> </h:column> </h:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Tyler Johnson
made changes -
Description |
Consider the following source code: @SessionScoped public class A implements Serializable{ @PostConstruct public void init(){ System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } } and a second bean: @SessionScoped public class B implements Serializable{ @PostConstruct public void init(){ System.out.println("B Created "); } public List<String> getB(){ return Arrays.asList("B", "B"); } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <h:dataTable value="#{b}" var="_b"> <h:column> <ice:outputText value="#{_b}"/> </h:column> </h:dataTable> </ice:panelTab> <ice:panelTab label="3"> <h:dataTable value="#{a}" var="_a"> <h:column> <ice:outputText value="#{_a}"/> </h:column> </h:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Consider the following source code (BeanA and BeanB source is the same): @ManagedBean @SessionScoped public class BeanA implements Serializable { private List<String> a; @PostConstruct public void init(){ Thread.dumpStack(); System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } public void setA(List<String> b) { a = a; } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Tyler Johnson
made changes -
Attachment | sc10442.war [ 13491 ] |
Tyler Johnson
made changes -
Description |
Consider the following source code (BeanA and BeanB source is the same): @ManagedBean @SessionScoped public class BeanA implements Serializable { private List<String> a; @PostConstruct public void init(){ Thread.dumpStack(); System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } public void setA(List<String> b) { a = a; } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Consider the following source code (BeanA and BeanB source is the same): @ManagedBean @SessionScoped public class BeanA implements Serializable { private List<String> a; @PostConstruct public void init(){ Thread.dumpStack(); System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } public void setA(List<String> b) { a = a; } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Tyler Johnson
made changes -
Description |
Consider the following source code (BeanA and BeanB source is the same): @ManagedBean @SessionScoped public class BeanA implements Serializable { private List<String> a; @PostConstruct public void init(){ Thread.dumpStack(); System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } public void setA(List<String> b) { a = a; } } and finally the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Consider the following source code (BeanA and BeanB source is the same): @SessionScoped public class BeanA implements Serializable { @PostConstruct public void init(){ System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } } and the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Tyler Johnson
made changes -
Description |
Consider the following source code (BeanA and BeanB source is the same): @SessionScoped public class BeanA implements Serializable { @PostConstruct public void init(){ System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } } and the view: <h:form> <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> </h:form> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Consider the following source code (BeanA and BeanB source is the same): @SessionScoped public class BeanA implements Serializable { @PostConstruct public void init(){ System.out.println("A Created "); } public List<String> getA(){ return Arrays.asList("A", "A"); } } and the view: <ice:panelTabSet> <ice:panelTab label="1"> </ice:panelTab> <ice:panelTab label="2"> <ice:dataTable value="#{beanB.b}" var="_b"> <ice:column> <ice:outputText value="#{_b}" /> </ice:column> </ice:dataTable> </ice:panelTab> <ice:panelTab label="3"> <ice:dataTable value="#{beanA.a}" var="_a"> <ice:column> <ice:outputText value="#{_a}" /> </ice:column> </ice:dataTable> </ice:panelTab> </ice:panelTabSet> If you navigate to tab 2, the first bean´s init method will be called ("B Created"). Then navigate to tab 3 and you will see the same for A ("A created"). If you swap out the h:dataTable/h:column and replace it with it´s ice equivalents and retry the above test, both B and A are created at the same time when you click on tab 2 (("B Created" & "A Created"). Having all getters called can hurt performance since they may contain expensive logic such as DB accesses, etc.. |
Ken Fyten
made changes -
Fix Version/s | EE-2.0.0.GA_P01 [ 10271 ] | |
Fix Version/s | 2.1 [ 10241 ] | |
Assignee Priority | P2 | |
Assignee | Mark Collette [ mark.collette ] |
Ken Fyten
made changes -
Assignee | Mark Collette [ mark.collette ] | yip.ng [ yip.ng ] |
Ken Fyten
made changes -
Assignee Priority | P2 | P1 |
yip.ng
made changes -
Attachment | screenshot-01.png [ 13509 ] |
Repository | Revision | Date | User | Message |
ICEsoft Public SVN Repository | #25440 | Fri Sep 09 09:47:03 MDT 2011 | yip.ng | |
Files Changed | ||||
MODIFY
/icefaces2/trunk/icefaces/compat/components/src/main/java/com/icesoft/faces/component/panelseries/UISeries.java
|
Repository | Revision | Date | User | Message |
ICEsoft Public SVN Repository | #25441 | Fri Sep 09 10:20:05 MDT 2011 | yip.ng | |
Files Changed | ||||
MODIFY
/icefaces2/branches/icefaces-2.0.x-maintenance/icefaces/compat/components/src/main/java/com/icesoft/faces/component/panelseries/UISeries.java
|
yip.ng
made changes -
Status | Open [ 1 ] | Resolved [ 5 ] |
Resolution | Fixed [ 1 ] |
Ken Fyten
made changes -
Fix Version/s | 2.1-Beta [ 10291 ] | |
Fix Version/s | 2.1 [ 10241 ] |
Evgheni Sadovoi
made changes -
Ken Fyten
made changes -
Assignee | yip.ng [ yip.ng ] | Mark Collette [ mark.collette ] |
Ken Fyten
made changes -
Status | Resolved [ 5 ] | Closed [ 6 ] |
Mark Collette said:
Ok, basically the problem is that we've got an incomplete implementation of visitTree, which assumes that it needs to iterate over the dataTable rows, when it should not since we're only doing state restoration, that causes the side effect of loading the dataTable's DataModel and thus loading the beans. Nils has already solved this in the ACE dataTable by adding this guard:
public boolean visitTree(VisitContext context, VisitCallback callback) {
boolean ret = false;
if (this.isVisitable(context)) {
boolean visitRows = requiresRowIteration(context); // *** Here ***
int savedIndex = -1;
{ // *** Here *** savedIndex = getRowIndex(); setRowIndex(-1); }if (visitRows)
...
if (visitRows) setRowIndex(savedIndex); // *** Here ***
...
}
private boolean requiresRowIteration(VisitContext ctx) {
{ // Use JSF 2.1 hints if available return !ctx.getHints().contains(VisitHint.SKIP_ITERATION); }try
catch (NoSuchFieldError e)
{ FacesContext fctx = FacesContext.getCurrentInstance(); return (!PhaseId.RESTORE_VIEW.equals(fctx.getCurrentPhaseId())); }}