tag:blogger.com,1999:blog-350205692009-02-20T19:29:08.220-08:00Andrés TestiAndrés Testihttp://www.blogger.com/profile/16389222274573646435noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-35020569.post-1159991215058204162006-10-04T12:28:00.000-07:002006-10-10T03:18:15.223-07:00An Implicit Query Proposal for EJB3<style type="text/css">-- @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } --></style><span style="font-family:Arial,sans-serif;"></span><div style="text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB">(<a href="http://andrestestihispano.blogspot.com/2006/10/propuesta-para-consultas-implcitas-en.html">Spanish Version</a></span></span><span lang="en-GB">)<br /><br />When we are working with ORM technologies, it's commonly suggested to separate Business Logic component in two tiers. Persistence tier groups all object that are mapped to tables in a data base. This tier acts as a data container with low functionality because it can't access to query API. In the other hand, we have the DAO (Data Access Object) tier, in charge of manage transactions, queries, insertions and updates. A good practice is to make a DAO class for each persistent class in the model component. DAO tier can see persistence tier, but persistent tier can not see DAO tier. This architecture design looks easy to develop. But objects with parent to children relationships (in navigation sense, not inheritance sense) create a new problem. If we need to update a child: Must we invoke a DAO related to the parent, or a DAO related to the child? What´s happen if we delete a parent object which must do a cascading delete over its children? Must we call the child DAO to delete each instance separately? The answer is not simple, and neither unique but it makes sense to centralize all the logic as possible in the persistence tier in order to reduce the DAO tier and minimize inconsistencies in the design pattern. A</span> lighter DAO could be the key<span lang="en-GB"> to solve some of these troubles. EJB3 have the Entity Listener feature, where an entity listener accesses to entity lifecycle (CRUD) in an orthogonal way to reduce DAO responsibilities. The DAO query logic is reduced due to entity relationships that act as transparent queries.</span> At this moment there no other contribution to the transparency in the query world.<br /><span style="font-family:Arial,sans-serif;"><span style="background: transparent none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span lang="en-GB"> Imagine that a salesman salary is calculated as the sum of all values of his sales. To contribute with the centralization of responsibilities, we can define a query as a named query related to Salesman class. The only tier in our architecture which is able to execute this query is the DAO tier.</span></span></span></div> <p style="margin-bottom: 0cm; font-family: courier new; color: rgb(0, 102, 0);" lang="en-GB">@Entity<br />@NamedQuery(<br />name=”Salesman.calculateSalary”,<br />query=<br />”SELECT SUM(sale.value) “ +<br />“FROM Salesman s JOIN s.sales sale ” +<br />“WHERE s = :salesman “<br />)</p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">public class Salesman{<br />....<br />@OneToMany(fetch=LAZY, cascade={ALL}, mappedBy=”salesman”)<br />private List<sale> getSales;<br />.....<br />}</sale></span><br /></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">public class Sale{<br />.....<br />@ManyToOne(fetch=LAZY, optional=false)<br />@JoinColumn(name=”SALESMAN_ID”)<br />private Salesman salesman;</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> @Column(name=”VALUE”)<br />private Integer value;<br />....<br />}</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">@Stateless<br />public class DaoSalesmanBean implements DaoSalesmanLocal{</span></p><p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"><br />@PersistenceContext<br />private EntityManager em;</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"><br />public Long calculateSalary(Salesman s){<br />return(Long)em<br />.createNamedQuery(“Salesman.calculateSalary”)<br />.setParameter(“salesman”, s)<br />.getSingleResult();<br />}<br />}</span></p> <p style="margin-bottom: 0cm;" align="justify" lang="en-GB"> <span style="font-family:Arial,sans-serif;"><span lang="en-GB">Something is wrong here. Theoretically, objects in OOP have their own methods to retrieve their states. Why salesman salary must be retrieved by other object? Then, we can think in a new injection type, named <b>Implicit Query</b>. Imagine the next annotation type:</span></span></p><p style="margin-bottom: 0cm;" align="justify" lang="en-GB"><br /></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">@Retention(RUNTIME)<br />@Target(METHOD)<br />public @interface ImplicitQuery{<br /></span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">String value();<br />String parameter() default “this”;<br />FetchType fetch() default EAGER;</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">}</span></p> <p style="margin-bottom: 0cm;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> Where</span></span></p><p style="margin-bottom: 0cm;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"><b>value</b>: name of the related<span style="font-weight: bold;"> Named Query</span>.<br /><b> parameter</b>: name of the only query parameter. By default, this value is set to “this”<br /><b>fetch</b>: fetch type.</span></span></p> <p style="margin-bottom: 0cm;" lang="en-GB"><span style="font-family:Arial,sans-serif;"> Then, we can add the next field in Salesman class:</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">@ImplicitQuery(<br />name=”Salesman.calculateSalary”,<br />parameter=”salesman”<br />)<br />private Long salary;</span></p> <p style="margin-bottom: 0cm; text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> In this way, we can eliminate calculate Salary method in DaoSalesman class, reducing even more the responsabilities in DAO tier!!!</span></span></p><br /><span style="font-style: italic;font-family:Arial,sans-serif;" ><b>Implicit Queries Advantages:</b></span> <ul><li><p style="margin-bottom: 0cm;"><span style="font-family:Arial,sans-serif;"><b>Transparent Subqueries:</b></span></p> </li></ul> <p style="margin-bottom: 0cm; text-align: justify;" lang="en-GB"> <span style="font-family:Arial,sans-serif;">Imagine that a salesman take several salary advances, then we want to known which salary advance are greatest than salesman sales value sum. In the current EJB3 specification, we must work as follow:</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> SELECT s.salaryAdvance<br />FROM Salesman s<br />WHERE s = :salesman AND s.salaryAdvance.value > ALL(<br />SELECT SUM(sale.value)<br />FROM Sale sale<br />WHERE sale.salesman = :salesman<br />)</span></p> <p style="margin-bottom: 0cm;" lang="en-GB"><span style="font-family:Arial,sans-serif;"> But with an <span style="font-weight: bold;">Implicit Query</span> feature, the query looks as follow:</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> SELECT s.salaryAdvance<br />FROM Salesman s<br />WHERE s = :salesman AND s.salaryAdvance.value > s.salary</span></p> <p style="margin-bottom: 0cm;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> This is a more elegant solution than previous solution.</span></span></p> <ul><li><p style="margin-bottom: 0cm;"><span style="font-family:Arial,sans-serif;"><b>Typesafe</b>:</span></p> </li></ul> <p style="margin-bottom: 0cm; text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> If we associate an <span style="font-weight: bold;">Implicit Query</span> to a field or to a getter, EJB3 container can detect type inconsistency of property and query return in deployment time. This feature, aids us to early detect type errors.</span></span></p> <p style="margin-bottom: 0cm;" align="justify" lang="en-GB"> <span style="font-family:Arial,sans-serif;"> For example:</span></p> <p style="margin-bottom: 0cm;" align="justify" lang="en-GB"> </p> <p style="margin-bottom: 0cm;" lang="en-GB"><span style="color: rgb(0, 102, 0);font-family:Courier New,monospace;" > // these lines throws a deployment time exception, because<br />// property type is String, but the query returns a Long<br />@ImplicitQuery(name=”Salesman.calculateSalary”)<br />private String salary;</span><br /></p> <ul><li><p style="margin-bottom: 0cm;" align="justify"><span style="font-family:Arial,sans-serif;"><b>Polimorphism</b>:</span><br /></p> </li></ul> <div style="text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> If, besides a salesmen, our enterprise has administrative employees, and their salaries are calculated as sum of their working hours, we can generalized both classes in a Employee superclass. </span></span></div><p style="margin-bottom: 0cm;" align="justify"> </p> <p style="margin-bottom: 0cm;" align="justify"><span style="font-family:Arial,sans-serif;"><span lang="en-GB">Declarations become as follows:</span></span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> public class Employee{...}</span><br /></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> @Entity</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">@NamedQuery(<br />name=”AdministrativeEmployee.calculateSalary”,<br />query=<br />”SELECT SUM(wh.value) ” +<br />“FROM “ +<br />“ AdministrativeEmployee a “ +<br />“ JOIN a.workingHours wh “ +<br />“WHERE a = :admEmployee”<br />)<br />public class AdministrativeEmployee extends Employee{...}</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> @Entity<br />@NamedQuery(<br />name=”Salesman.calculalteSalary”,<br />query=<br />”SELECT SUM(sale.value) “ +<br />“FROM Salesman s JOIN s.sales sale ” +<br />“WHERE s = :salesman “<br />)<br />public class Salesman extends Employee{....}</span></p> <p style="margin-bottom: 0cm;" lang="en-GB"> </p> <p style="margin-bottom: 0cm;" lang="en-GB"> <span style="font-family:Arial,sans-serif;">In current EJB3 specification , DaoEmployee looks as follows:</span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;"> public Long calculateSalary(Employee e){<br />if(e instanceof AdministrativeEmployee){<br />return(Long)em.createNamedQuery(<br />“AdministrativeEmployee.calculateSalary”<br />).setParameter(“admEmployee”, e).getResultList();<br />}else{<br />return(Long)em<br />.createNamedQuery(“Salesman.calculateSalary”)<br />.setParameter(“salesman”, e)<br />.getResultList();<br />}<br />}</span></p> <p style="margin-bottom: 0cm;" lang="en-GB"> </p> <p style="margin-bottom: 0cm; text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> As you can see, this solution is distant to OOP good practices. Design can result more complex, if there are more Employee subclasses. With an implicit query feature, this method is not necessary, simply you must define an <span style="font-weight: bold;">Implicit Query</span> for each Employee subclass, then the result is obtained as follows:</span></span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);"><span lang="en-GB"> employee<span style="font-family:Courier New,monospace;">.getSalary();</span></span></p> <p style="margin-bottom: 0cm;" lang="en-GB"> </p> <p style="margin-bottom: 0cm; text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"> In an EJBQL context, we can economize a lot of queries. For example, if we need to find all employees with a salary lower than 3000 without an implicit query feature, we must to write a subquery for each employee subclass:</span></span></p> <p style="margin-bottom: 0cm; color: rgb(0, 102, 0);" lang="en-GB"><span style="font-family:Courier New,monospace;">SELECT DISTINCT(e)<br />FROM AdministrativeEmployee a, Salesman s<br />WHERE (<br />a = :employee AND 3000 > (<br />SELECT SUM(wh.value)<br />FROM<br />AdministrativeEmployee a1<br />JOIN a1.workingHours wh<br />WHERE a1 = :employee<br />)<br />)OR(<br />s = :employee AND 3000 > (<br />SELECT SUM(sale.value)<br />FROM Salesman s1 JOIN s1.sales sale<br />WHERE s1 = :salesman<br />)<br />)</span></p> <p style="margin-bottom: 0cm;" lang="en-GB"><span style="font-family:Arial,sans-serif;"> Having an <span style="font-weight: bold;">Implicit Query </span>feature, previous code is reduced to:</span></p> <p style="margin-bottom: 0cm;" lang="en-GB"><span style="font-family:Arial,sans-serif;"><span style="color: rgb(0, 102, 0);"> SELECT e</span><br /><span style="color: rgb(0, 102, 0);">FROM Employee e</span><br /><span style="color: rgb(0, 102, 0);">WHERE e.salary &lt; 3000</span></span></p><p style="margin-bottom: 0cm;" lang="en-GB"><span style="font-family:Arial,sans-serif;"><span style="color: rgb(0, 102, 0);"><br /></span></span></p> <ul><li><span style="font-family:Arial,sans-serif;"><b>Simplified expressions in Bean contexts:</b></span></li></ul> <p style="margin-bottom: 0cm; text-align: justify;"><span style="font-family:Arial,sans-serif;"><span lang="en-GB"><span style="font-weight: bold;"> Implicit Query</span>, simplifies access to queries in the Expression Language, because it's possible to access the query result simply accessing a <b>bean</b> property.</span></span></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35020569-115999121505820416?l=andrestesti.blogspot.com'/></div>Andrés Testihttp://www.blogger.com/profile/16389222274573646435noreply@blogger.com3