using DTO with Seam apps
asookazian Aug 21, 2009 7:21 PMOne of the benefits of using Seam is that it acts as the glue
between the web technology and the server-side technology. By this we mean that the Seam Framework allows us to use enterprise beans (for example, Session Beans) directly within the Web tier without having to use Data Transfer Object (DTO) patterns and without worrying about exposing server-side functionality on the client.
source: http://www.packtpub.com/article/developing-seam-applications
What about cases where your JPAQL query returns more than one value (whether scalar or entity or both) in the select clause? JPA/Hibernate returns a Object[] when there is more than one value, be it scalar or entity, in the select clause for a JPQL/HQL query (least common denominator tactics obviously, which makes sense).
Then, in your JSF page while you are iterating thru the List in a dataTable, for example, you end up having to use array index references to extract the data from the Object[] array instances that are in the List<Object[]> that may have been outjected via @DataModel in your backing bean or DAO component.
In the case of read-only data, it's ok to use the DTO (which is (un)officially an anti-pattern in EE 5 with the advent of JPA entity classes?)
Is using DTOs to prevent array index referencing (i.e. hard-coding which is always dangerous!) of Object[] arrays a best or bad practice in these situations?
Here is a simple example to illustrate the scenario using a theta-join:
List<Object[]> myList = entityManager.createQuery(+ " select foo, bar from Foo foo, Bar bar "+ " where bar.fooId = foo.fooId ").getResultList();
Or using ANSI sql syntax:
List<Object[]> myList = entityManager.createQuery(+ " select foo, bar from Foo as foo join foo.bar as bar ").getResultList();
Refactor:
List<GenericDTO> myList = entityManager.createQuery(+ " select new com.your.company.CustomerInformationDTO( foo, bar ) from Foo as foo join foo.bar as bar ").getResultList();
Now in your JSF, you can use this type of code in your EL:
<a4j:repeat value="#{customerInformationList}" var="customerInformationDTO"> <s:decorate template="layout/edit.xhtml"> <ui:define name="label">Site: </ui:define> <h:outputText value="#{customerInformationDTO.listValue.description}"/> </s:decorate> </a4j:repeat>
Rather than using:
<a4j:repeat value="#{customerInformationList}" var="customerInformation"> <s:decorate template="layout/edit.xhtml"> <ui:define name="label">Site: </ui:define> <h:outputText value="#{customerInformation[1].description}"/> </s:decorate> </a4j:repeat>
See what I mean?
So what's the best way to handle this in two scenarios?
1) when your data is read-only
2) when your data is updateable (CUD)