views:

147

answers:

1

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!

+6  A: 

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

  • It is readable
  • It is maintainable

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"&gt;
<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)

JBoss Seam: Agile RIA Development Framework

Arthur Ronald F D Garcia
Wow! Now THAT'S a detailed answer. Thanks so much for your insight!
Shadowman
Right, Arthur is the Seam guy here :)
BalusC
Nice answer. But I would stay away of Seam Application Framework. (EntityHome, EntityQuery etc)
Shervin
@Shervin I know, but i said you can override its methods if you want
Arthur Ronald F D Garcia