I've really taken a liking to the JBoss Seam application framework. Since the notion of injection/outjection and tight integration between JSF/EJBs/JPA is relatively scarce among Java application frameworks, I was looking for some good resources for design patterns and best practices for using this framework. I've poured over the examples and several books on the subject. However, I'm more interested in real-world design patterns that compare to the traditional J2EE design patterns. For example, traditional DAOs vs. EntityHome/EntityQuery. Where should business logic be performed? In Action classes? Or in dedicated service classes? I'd really appreciate any insight experienced Seam developers can give. Thanks!
There is a lot of useful patterns you can use.
Traditional approach
view >> controller >> service >> domain
Which can be Translated To
/**
* view
*/
<h:commandButton value="Deposit" action="#{accountController.removeAccount(account)}"/>
/**
* controller
*/
@Name("accountController")
public class AccountController implements Serializable {
/**
* Usually a plain POJO or EJB
*/
private @In AccountService accountService;
public void removeAccount(Account account) {
accountService.removeAccount(account);
}
}
/**
* service
*/
@Name("accountService")
public class AccountServiceImpl implements AccountService {
private @In EntityManager entityManager;
public void removeAccount(Account account) {
entityManager.remove(account);
}
}
If you have some actions which needs To manipulate JSF components on The server-side, use a controller as shown above can be a nice idea
You can also use
view >> service >> domain
It is basically The same approach shown above but without controller
Or by using built-in mediator pattern by using EntityHome / EntityQuery
view >> domain
Register your EntityHome as follows /WEB-INF/components.xml
<framework:entity-home name="accountHome" entity-class="br.com.ar.seam.Account"/>
Now you can create an alias by using factory element
<factory name="account" value="#{accountHome.instance}"/>
/**
* view
*
* Notice account will be evaluated as accountHome.instance
*/
<h:commandButton value="Deposit" action="#{account.remove}"/>
Nothing else. Keep in mind when using Either EntityHome (JPA) or HibernateEntityHome (Hibernate) you usually need To override some methods To improve performance as follows
@Name("accountHome")
public class AccountHome extends EntityHome<Account> {
/**
* Override any method you want right here
*/
}
About business logic ??? You can put it inside your service layer or you can use domain-driven-design approach. See here which fits better what you want
Testing: Use Seam bundled Testing components. Take a look at Seam examples directories To get an overview how you can perform Testing without deployment
If possible, use seam-gen To generate your project. Seam in Action book, chapter 2, can gives a good insight how To startup seam-gen capabilities. read carefully. Any seam-gen generated project can be opened and Tested in NetBeans and Eclipse
JSF components: Take a look at here
There is more: Do not use @Out-jection anymore. Use @Factory instead. @Out-jection will be deprecated in favor of @Factory method.
I Think queries is better stored inside an external file because
As follows
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<query name="GIFT_CARDS_WITH_BUYER">
<![CDATA[
from
GiftCard c
left join fetch
c.buyer
where
c.recipientNotificationRequested = 1
]]>
</query>
<query name="GIFT_CARDS_WITHOUT_NO_RELATIONSHIP">
<![CDATA[
from
GiftCard
]]>
</query>
</hibernate-mapping>
Nice one, don't
Another resource goes here (pdf format)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With