just one comment:
Calling .flush() on every alteration really should not be promoted as a good practice.
/max
On Sep 22, 2011, at 24:22, Dan Allen wrote:
Here's some additional feedback I received from a community
member a while back...to merge it into this thread.
(begin feedback)
...from being burned from 3 seam based customers with apps and maintenance. The
"Home" or any other name should be just be put into a grave and slowly cast away
to sea ;). It is too heavy and complicated and just about anything inherited (extends)
truly causes heartache[Favor Composition over inheritance: Effective Java]. The current
seam home has a few super classes above the home and when you try to unit test it (the
standard definition of unit-testing including isolation) you get the "No Active
Application Context Found (if I remember it right). That happens because it is tightly
coupled with the application. But not to be hard on Home, I do realize the history of the
home object and know it was developed when EL had no parameters. So I have learned a lot
since then and I here are some things that I can impart to Seam 3.
1. My "Home" now is a "ServiceBean", and I have one for each
"Major" entity, see below. I have really stewed over this over months and
months, and the "Home" of "ServiceBean" should be kept small, focused,
reusable, tested and untouched. It's only task is to update, persist, possibly
remove, or some other functions that are required. In my example below I have custom
close action. Notice also that although these beans are stateful that doesn't mean
everything should be, so in these methods I have the parameter of what is being needed to
be updated, and not a field. In other words I don't have @In private Job job, I opted
for public boolean update(job). Mostly because, again, I want to make this service bean
reusable so whether I have a #{newJob}, #{copyOfAJob}, or #{managedJob} or whatever
component of job I need to work on I only need one jobServiceBean to cater to all my jobs,
in whatever conversation I am using. I also fire events from here if I need to do that.
After this is tested, and what I need I usually don't touch it anymore. If I need to
enhance I either use a decorator pattern around it, or enhance it in an @Observer.
I'll email about that later.
@Name("jobServiceBean")
@Scope(ScopeType.CONVERSATION)
public class JobServiceBean implements JobService {
private EntityManager entityManager;
private StatusMessages statusMessages;
@In
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@In
public void setStatusMessages(StatusMessages statusMessages) {
this.statusMessages = statusMessages;
}
public boolean update(Job job) {
this.entityManager.flush();
this.statusMessages.add(StatusMessage.Severity.INFO, "Successfully updated
job {0}", job.getName());
return true;
}
public boolean close(Job job) {
job.setJobStatus(JobStatus.CLOSED);
this.entityManager.flush();
this.statusMessages.add(StatusMessage.Severity.INFO, "Successfully closed
job {0}", job.getName());
return true;
}
}
2. One thing you may have noticed from above that there is no 'instance' field
with corresponding getters or setters like the old 'Home'. So the ServiceBean in
my case is not a full crud, but CUD + your own business methods. That's because that
too should be decoupled because we never know the source of the object is. Is the object
created from a factory? from a copy? is it a mapped component, a managed component?
Creation of objects or loading of objects, or the manufacturing of objects from factories
should be separate from the "home" or in my case the "ServiceBean".
(end feedback)
--
Dan Allen
Principal Software Engineer, Red Hat | Author of Seam in Action
Registered Linux User #231597
http://www.google.com/profiles/dan.j.allen#about
http://mojavelinux.com
http://mojavelinux.com/seaminaction
_______________________________________________
forge-dev mailing list
forge-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/forge-dev