0

Suppose I have an abstract entity class Employee, and two concrete entity subclasses, FullTimeEmployee and PartTimeEmployee. Each of the two have attributes of their own.

Now, If I want to display all employees of both classes, mixed in a single datatable. Calling a bean, that make a query to EntityManager and that returns a List. For that I would do

<h:dataTable value=#{backingBean.employeeList} var="emp">
   <h:column><h:outputText value=#{emp.name}</h:column>
   <h:column><h:outputText value=#{emp.phone}</h:column>
// more properties of father class...
</h:dataTable>

but, what would be correct way for showing the attributes of the subclasses?, if I put one attribute of a FullTimeEmployee, it would throw an exception when trying to access that attribute in other classes.

I thought I could use

  <c:if test="#{emp.class=='FullTimeEmployee'}">
      <h:outputText value="#{emp.salary}"> </c:if>

But I don't think that is correct to write if's , better would be to use polymorphism, and let the entity know how to represent itself in screen/view. So question is, how can I make the entity to know how to represent itself on screen?, how can I delegate this responsibility to an entity?

I'd prefer to write XHTML code inside an entity class, rather than write entity code inside a view.

Regards

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Leandro Alsina
  • 183
  • 1
  • 2
  • 13

1 Answers1

0

The <c:if> won't work this way for the reasons elaborated here: JSTL in JSF2 Facelets... makes sense? Make use of rendered attribute.

<h:outputText value="#{emp.salary}" rendered="#{...}" />

And no, you should absolutely not put the presentation logic in the model, but keep it in the view. The way how you're checking the class is however indeed not correct. Firstly, class is a reserved keyword in Java and therefore not allowed as EL property. You'd need to quote it like so ['class']. Secondly, you can't compare a Class<T> to a String like this, you'd need to compare Class#getSimpleName() instead.

<h:outputText value="#{emp.salary}" rendered="#{emp['class'].simpleName == 'FullTimeEmployee'}" />

Add if necessary an additional type property to the model so that you don't need to check the class name, which is indeed ugly.

<h:outputText value="#{emp.salary}" rendered="#{emp.type == 'FULLTIME'}" />

If it's a larger bunch of presentation logic, just refactor to an include or tagfile.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555