Re: about Beanform and JPA (persistence)

2006-12-13 Thread Cyrille37

Hello Sam,

Thanks a lot for your long long explanation. It was really wonderfull 
for me.

Now I've understood some architecture's best practices.

I've applied your methods to my little project using Spring2.

Now I would like to practice the same little project with an Application 
Server. I've installed Glassfish.
I will use Tapestry for the Web UI and make EJBs for services (business 
layer).


So I've had a look at Hivemind's documentation about accessing EJBs from 
Hivemind to inject theirs references in Tapestry.
But the service hivemind.lib.EJBProxyFactory Service seems to handle 
only Stateless session bean 
(http://hivemind.apache.org/hivemind-lib/EJBProxyFactory.html).


So is it not possible to integrate Tapestry with EJBs services with 
Hivemind ?

Have I to integrate Spring to permit Tapestry / EJBs interaction ?

Thanks again to my master ;o)
Best regards from your disciple.
Cyrille.


Sam Gendler a écrit :

I'll clarify a little.  In general, you want to keep persistence code,

...

OK, that was a ton of information, but hopefully you'll find it very
useful, since you said you were new to Java web development.

--sam





-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: about Beanform and JPA (persistence)

2006-12-13 Thread andyhot
Cyrille37 wrote:
 Hello Sam,

 Thanks a lot for your long long explanation. It was really wonderfull
 for me.
 Now I've understood some architecture's best practices.

Indeed it was very helpful. Can't wait to see how
http://wiki.apache.org/tapestry/AnnotatedGuideToTapestrySource
develops!

BTW, I've found Pojos in action to be
an excellent resource on the subject.


 I've applied your methods to my little project using Spring2.

 Now I would like to practice the same little project with an
 Application Server. I've installed Glassfish.
 I will use Tapestry for the Web UI and make EJBs for services
 (business layer).

 So I've had a look at Hivemind's documentation about accessing EJBs
 from Hivemind to inject theirs references in Tapestry.
 But the service hivemind.lib.EJBProxyFactory Service seems to handle
 only Stateless session bean
 (http://hivemind.apache.org/hivemind-lib/EJBProxyFactory.html).

 So is it not possible to integrate Tapestry with EJBs services with
 Hivemind ?
 Have I to integrate Spring to permit Tapestry / EJBs interaction ?

 Thanks again to my master ;o)
 Best regards from your disciple.
 Cyrille.


 Sam Gendler a écrit :
 I'll clarify a little.  In general, you want to keep persistence code,
 ...
 OK, that was a ton of information, but hopefully you'll find it very
 useful, since you said you were new to Java web development.

 --sam




 -
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]





-- 
Andreas Andreou - [EMAIL PROTECTED] - http://andyhot.di.uoa.gr
Tapestry / Tacos developer
Open Source / J2EE Consulting 


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: about Beanform and JPA (persistence)

2006-12-08 Thread Cyrille37

Hello professor Sam ;o)

Thank you a lot for you long long course.
I will read it slowly and carefully this morning in the train.

Best Regards,
Cyrille.

Sam Gendler a écrit :

I'll clarify a little.  In general, you want to keep persistence code,
ui code, and business rules fairly separate.  This will keep your
application much more flexible as more and more requirements are added
over time.

In your example code, you've got persistence embedded directly in ui
code.  Should you ever decide to replace your perisistence layer with
something else (say, replace toplink with hibernate, ibatis, or even
raw jdbc), you will have to go in and modify every page class you've
built that has persistence code in it.  In a large project, this is
effectively impossible to do without destabilizing the codebase too
much to be acceptable.  Therefore, most well architected apps will
keep all perisistence code in a separate set of interfaces.  So long
as you can create a persistence layer that maintains the same
interface, you can replace one with another very simply.  This is
where dependency injection becomes useful - Instead of injecting a
toplink data access object into your page, you can inject a hibernate
one instead.

But wait, did I just say injecting a dao into the page?  Most of us
would argue you never want to do that, for the following reason.
Suppose you have a method in your DAO which stores an entity into the
database.  If you are using your dao directly in your page class, then
you either have to open and commit a transaction directly in your page
(violating the rule about keeping persistence code out of your ui
layer and once again locking you into a particular transaction
mechanism, preventing you from switching between JDBC transactions,
JTA transactions, etc), or else your DAO itself has to open the
transaction, save the entity, and commit the transaction.  This would
be fine in this circumstance.  Your persistence code would stay in
your persistence layer, but now you have another problem.  Page1 may
store just a single instance of the entity, so including transaction
semantics around that store operation works just fine.  But now you
have to add Page2, and Page2 wants to store two entities.  But if
either store() fails (unique column conflict, for instance), you don't
want to store() either of the entities.  So now your transaction
within the store method won't work, since the first store() will be
fully committed before the second store() fails, offering you no way
to roll back.  So your only option is to implement another DAO method
- one which takes a collection of entities and stores them all within
a single transaction.  You can probably see that as your project
grows, you are going to wind up with a lot of very similar methods,
each different only in the transaction behaviour.

The rule that you must be able to store both entities if you are going
to store either one is considered a 'business rule' - an artificial
constraint on what you are allowed to do.  Business rules frequently
change over the life of a project, so once again, you want to keep
your business logic firmly separated from your ui.  Again, this is
accomplished by shoving your business logic into separate classes with
a well defined interface and injecting instances of those interfaces
into your page classes.  Now, your ui code doesn't need to know
anything about transactions because your service layer is handling
them.  Your ui can call a method to store() two entities and doesn't
need to be concerned with the details of how that occurs or what is
allowed.  All it knows is it either succeeded or failed based on an
exception may catch. Once again, your ui layer is clean.  It is
injected only with service interfaces.  Service objects are injected
with DAO interfaces, and you've got a nice clean layer separation.

Except for one thing.  You've got a bunch of transaction code sitting
in your service layer, wrapped around calls into your DAOs, which no
longer have any knowledge of transactions themselves.  This means
there is still a strong binding between your service layer and your
perisistence layer, making it very difficult to modify one without
modifying the other.  That's generally considered a _bad_thing_ and
should be avoided.  So this is where Spring steps in and provides some
VERY useful functionality.  Spring gives a nice declarative mechanism
(ie. you can set it up in a config file or annotation, rather than by
writing code)  for forcing a transaction around any method of any
object.  You can define a business method that calls multiple DAO
methods and you can tell spring that anytime someone calls that
method, you want a transaction to be started before the method
executes, and the transaction to be committed when the method is
completed without throwing an exception, or rolled back if an
exception is caught.  Now you can remove all of that pesky transaction
code from your service layer, giving you true independance from 

Re: about Beanform and JPA (persistence)

2006-12-07 Thread DJ Gredler

I haven't used EntityManagers directly, but your code looks fine to me,
especially if it works ;-)

You may want to wrap your flush( ) call in a try/catch block in case
something goes wrong, and roll back the transaction in the catch block.

Once you get more comfortable with things (and if you're using Hibernate),
you may want to check out some of the integration packages (Tapernate,
Honeycomb, etc) that handle transaction scoping for you. Spring might also
be a good option if you end up splitting your app up into presentation /
service / persistence layers.

On 12/6/06, Cyrille37 [EMAIL PROTECTED] wrote:


Hello,

I'm coming back with a beginner question ;-)

After 3 weeks of Java Web App discovering, I'm actually working with
Tapestry 4.0.2, Netbeans 5.5 which give me easy data persistence support
with JPA Toplink essential, and Tomcat5.5 and Mysql5.

So I've finaly got something working with Beanform and JPA and I come to
you to get comments and ideas and best practice.

For the persistence, the method I've found is to do the following :

* To remember with object I'm playing with :

@Persist(client)
public abstract int getProductId();
public abstract void setProductId(int productId);

* To manage the Beanform's bean :

private Product _product ;
public Product getProduct()
{
if( this._product==null  this.getProductId()0 )
{
this.setProduct(  this.loadProduct( this.getProductId ()) );
}
return this._product ;
}

public void setProduct( Product product )
{
this._product = product ;
}

* For initializing the page at the first time :

public void activateExternalPage(Object[] parameters, IRequestCycle
cycle)
{
int pid = Integer.parseInt( parameters[0].toString());
setProductId( pid );
this.setProduct ( this.loadProduct(pid) );
}

* And finally to implement the Beanform 'save' listener :

public String save()
{
System.out.println( ProductEdit.save() );
if( this.getDelegate().getHasErrors() )
return null;
EntityManager em = getDataManagerFactory().GetEntityManager();
/*** I find that method a beat strange but it works ! ***/
em.getTransaction ().begin();
em.flush();
em.getTransaction().commit();

return Home;
}

Thanks to have read my poetry ;-)
Cyrille.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Re: about Beanform and JPA (persistence)

2006-12-07 Thread Sam Gendler

I'll clarify a little.  In general, you want to keep persistence code,
ui code, and business rules fairly separate.  This will keep your
application much more flexible as more and more requirements are added
over time.

In your example code, you've got persistence embedded directly in ui
code.  Should you ever decide to replace your perisistence layer with
something else (say, replace toplink with hibernate, ibatis, or even
raw jdbc), you will have to go in and modify every page class you've
built that has persistence code in it.  In a large project, this is
effectively impossible to do without destabilizing the codebase too
much to be acceptable.  Therefore, most well architected apps will
keep all perisistence code in a separate set of interfaces.  So long
as you can create a persistence layer that maintains the same
interface, you can replace one with another very simply.  This is
where dependency injection becomes useful - Instead of injecting a
toplink data access object into your page, you can inject a hibernate
one instead.

But wait, did I just say injecting a dao into the page?  Most of us
would argue you never want to do that, for the following reason.
Suppose you have a method in your DAO which stores an entity into the
database.  If you are using your dao directly in your page class, then
you either have to open and commit a transaction directly in your page
(violating the rule about keeping persistence code out of your ui
layer and once again locking you into a particular transaction
mechanism, preventing you from switching between JDBC transactions,
JTA transactions, etc), or else your DAO itself has to open the
transaction, save the entity, and commit the transaction.  This would
be fine in this circumstance.  Your persistence code would stay in
your persistence layer, but now you have another problem.  Page1 may
store just a single instance of the entity, so including transaction
semantics around that store operation works just fine.  But now you
have to add Page2, and Page2 wants to store two entities.  But if
either store() fails (unique column conflict, for instance), you don't
want to store() either of the entities.  So now your transaction
within the store method won't work, since the first store() will be
fully committed before the second store() fails, offering you no way
to roll back.  So your only option is to implement another DAO method
- one which takes a collection of entities and stores them all within
a single transaction.  You can probably see that as your project
grows, you are going to wind up with a lot of very similar methods,
each different only in the transaction behaviour.

The rule that you must be able to store both entities if you are going
to store either one is considered a 'business rule' - an artificial
constraint on what you are allowed to do.  Business rules frequently
change over the life of a project, so once again, you want to keep
your business logic firmly separated from your ui.  Again, this is
accomplished by shoving your business logic into separate classes with
a well defined interface and injecting instances of those interfaces
into your page classes.  Now, your ui code doesn't need to know
anything about transactions because your service layer is handling
them.  Your ui can call a method to store() two entities and doesn't
need to be concerned with the details of how that occurs or what is
allowed.  All it knows is it either succeeded or failed based on an
exception may catch. Once again, your ui layer is clean.  It is
injected only with service interfaces.  Service objects are injected
with DAO interfaces, and you've got a nice clean layer separation.

Except for one thing.  You've got a bunch of transaction code sitting
in your service layer, wrapped around calls into your DAOs, which no
longer have any knowledge of transactions themselves.  This means
there is still a strong binding between your service layer and your
perisistence layer, making it very difficult to modify one without
modifying the other.  That's generally considered a _bad_thing_ and
should be avoided.  So this is where Spring steps in and provides some
VERY useful functionality.  Spring gives a nice declarative mechanism
(ie. you can set it up in a config file or annotation, rather than by
writing code)  for forcing a transaction around any method of any
object.  You can define a business method that calls multiple DAO
methods and you can tell spring that anytime someone calls that
method, you want a transaction to be started before the method
executes, and the transaction to be committed when the method is
completed without throwing an exception, or rolled back if an
exception is caught.  Now you can remove all of that pesky transaction
code from your service layer, giving you true independance from your
persistence layer outside of the persistence interfaces, which should
be generic across any persistence mechanism.  OK, you've still got a
dependency in your config, but at 

about Beanform and JPA (persistence)

2006-12-06 Thread Cyrille37

Hello,

I'm coming back with a beginner question ;-)

After 3 weeks of Java Web App discovering, I'm actually working with 
Tapestry 4.0.2, Netbeans 5.5 which give me easy data persistence support 
with JPA Toplink essential, and Tomcat5.5 and Mysql5.


So I've finaly got something working with Beanform and JPA and I come to 
you to get comments and ideas and best practice.


For the persistence, the method I've found is to do the following :

* To remember with object I'm playing with :

   @Persist(client)
   public abstract int getProductId();
   public abstract void setProductId(int productId);

* To manage the Beanform's bean :

   private Product _product ;
   public Product getProduct()
   {
   if( this._product==null  this.getProductId()0 )
   {
   this.setProduct(  this.loadProduct( this.getProductId()) );
   }
   return this._product ;
   }

   public void setProduct( Product product )
   {
   this._product = product ;
   }

* For initializing the page at the first time :

   public void activateExternalPage(Object[] parameters, IRequestCycle 
cycle)

   {
   int pid = Integer.parseInt( parameters[0].toString());
   setProductId( pid );
   this.setProduct( this.loadProduct(pid) );
   }

* And finally to implement the Beanform 'save' listener :

   public String save()
   {
   System.out.println( ProductEdit.save() );
   if( this.getDelegate().getHasErrors() )
   return null;
   EntityManager em = getDataManagerFactory().GetEntityManager();
   /*** I find that method a beat strange but it works ! ***/
   em.getTransaction().begin();
   em.flush();
   em.getTransaction().commit();

   return Home;
   }

Thanks to have read my poetry ;-)
Cyrille.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]