Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > JPA in practice

Reply
Thread Tools

JPA in practice

 
 
Lew
Guest
Posts: n/a
 
      08-11-2009
JPA (Java Persistence API) makes promises about injection of references and
behavior through magic annotations like @Entity and @PersistenceContext. To
keep those promises, JPA apps must deploy into containers that know how to
inject, like GlassFish or Spring or (supposedly) Java Server Faces (JSF). You
can still use JPA without injection in a leaner Tomcat environment.

The key enablers to JPA are EntityManagerFactory and EntityManager. You
define a bunch of @Entity classes to pull database information into your
object model as value objects. Logic instances, i.e., business processes that
use these entities need an EntityManager to bind the objects to their data
store backing. For non-injected environments like plain Tomcat, you use a
static method to create the factory:

public class Util
{
private static final String PUNIT = "projectPU";
private static final EntityManagerFactory EMFCANON =
Persistence.createEntityManagerFactory( PUNIT );

public static EntityManagerFactory getEmf()
{
return EMFCANON;
}
}

The factory will be heavy but thread safe. Request processors get their
lightweight, non-thread-safe EntityManagers from the common factory:

public class BizProcess
{ ...
public String submit()
{
EntityManager emgr = Util.getEmf().createEntityManager();
try
{
Entity e = new Entity();
fill( e );
emgr.getTransaction().begin();
emgr.merge( e );
emgr.getTransaction().commit();
}
finally
{
emgr.close();
}
}
}

Not as sexy as @PersistenceContext() but it works.

--
Lew
 
Reply With Quote
 
 
 
 
Arved Sandstrom
Guest
Posts: n/a
 
      08-11-2009
Lew wrote:
> JPA (Java Persistence API) makes promises about injection of references
> and behavior through magic annotations like @Entity and
> @PersistenceContext. To keep those promises, JPA apps must deploy into
> containers that know how to inject, like GlassFish or Spring or
> (supposedly) Java Server Faces (JSF). You can still use JPA without
> injection in a leaner Tomcat environment.
>
> The key enablers to JPA are EntityManagerFactory and EntityManager. You
> define a bunch of @Entity classes to pull database information into your
> object model as value objects. Logic instances, i.e., business
> processes that use these entities need an EntityManager to bind the
> objects to their data store backing. For non-injected environments like
> plain Tomcat, you use a static method to create the factory:
>
> public class Util
> {
> private static final String PUNIT = "projectPU";
> private static final EntityManagerFactory EMFCANON =
> Persistence.createEntityManagerFactory( PUNIT );
>
> public static EntityManagerFactory getEmf()
> {
> return EMFCANON;
> }
> }
>
> The factory will be heavy but thread safe. Request processors get their
> lightweight, non-thread-safe EntityManagers from the common factory:
>
> public class BizProcess
> { ...
> public String submit()
> {
> EntityManager emgr = Util.getEmf().createEntityManager();
> try
> {
> Entity e = new Entity();
> fill( e );
> emgr.getTransaction().begin();
> emgr.merge( e );
> emgr.getTransaction().commit();
> }
> finally
> {
> emgr.close();
> }
> }
> }
>
> Not as sexy as @PersistenceContext() but it works.
>

If your client happens to still be wedded to OAS 10g (oc4j 10.1.3), with
EJB 2.5 (the best way to put it), and JSF 1.1, you still have to forgo
some of those nice annotations, and do things like you describe above.

We're pushing them to switch to Weblogic...it's a hard slog. These are
people that still use IE 6.

AHS
 
Reply With Quote
 
 
 
 
Tom Anderson
Guest
Posts: n/a
 
      08-11-2009
On Tue, 11 Aug 2009, Lew wrote:

> public class Util
> {
> private static final String PUNIT = "projectPU";
> private static final EntityManagerFactory EMFCANON =
> Persistence.createEntityManagerFactory( PUNIT );
>
> public static EntityManagerFactory getEmf()
> {
> return EMFCANON;
> }
> }
>
> The factory will be heavy but thread safe. Request processors get their
> lightweight, non-thread-safe EntityManagers from the common factory:
>
> public class BizProcess
> { ...
> public String submit()
> {
> EntityManager emgr = Util.getEmf().createEntityManager();
> try
> {
> Entity e = new Entity();
> fill( e );
> emgr.getTransaction().begin();
> emgr.merge( e );
> emgr.getTransaction().commit();
> }
> finally
> {
> emgr.close();
> }
> }
> }
>
> Not as sexy as @PersistenceContext() but it works.


Is there a convenient way to write code that gets an injected
EntityManager in a managed environment, but arranges its own provision in
an unmanaged one? Is that a meaningful thing to ask for?

tom

--
I think the Vengaboys compliment his dark visions splendidly well. -- Mark
Watson, on 'Do you listen to particular music when reading lovecraft?'
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      08-12-2009
Tom Anderson wrote:
> Is there a convenient way to write code that gets an injected
> EntityManager in a managed environment, but arranges its own provision
> in an unmanaged one? Is that a meaningful thing to ask for?


I have a way, but I won't know if it works until I succeed at getting an
injected one. Then I can compare the two scenarios.

For the factory:

public class Persistuff
{
public static final String PUNIT = "projectPU";

@PersistenceUnit( unitName=PUNIT )
private static EntityManagerFactory emf;

private static final EntityManagerFactory EMFCANON =
Persistence.createEntityManagerFactory( PUNIT );

public static EntityManagerFactory getEmf()
{
return (emf == null? EMFCANON : emf);
}
}

For the manager:
<http://java.sun.com/javaee/5/docs/tutorial/doc/bnbrm.html#bnbrp>

public class Bizzniss
{
@PersistenceContext
private EntityManager em;

public void run()
{
EntityManager mgr = (em != null? em
: Persistuff.getEmf().getEntityManager());
// use 'mgr' here
}
}

Unknown: resource consumption and packratting caused by injected values, if any.

Learning how to do this, I was running Glassfish 3 with a Postgres back end,
but my 4 GB RAM server box's power supply just gave up the ghost. Turns out
the combination of GF and PG with NetBeans was too much for my poor
single-core 64-bit workstation with only 1 GB RAM. Then I tried the
non-injective approach with Tomcat, Postgres and NetBeans. Turns out that
runs just great on the workstation.

That triggered a major "Hmmm." I may be on to a way to develop, deliver and
deploy full-blown custom apps very quickly with very low administrative and
hardware overhead.

Looks like JSF, JSP, JPA and servlets on Tomcat are a winning combination.
Once you factor in a few quirks.

(Bonus - Tomcat plays well with other environments like Apache Web Server and
many Java EE application servers.)

--
Lew
 
Reply With Quote
 
Arved Sandstrom
Guest
Posts: n/a
 
      08-12-2009
Lew wrote:
> Tom Anderson wrote:
>> Is there a convenient way to write code that gets an injected
>> EntityManager in a managed environment, but arranges its own provision
>> in an unmanaged one? Is that a meaningful thing to ask for?

>
> I have a way, but I won't know if it works until I succeed at getting an
> injected one. Then I can compare the two scenarios.
>
> For the factory:
>
> public class Persistuff
> {
> public static final String PUNIT = "projectPU";
>
> @PersistenceUnit( unitName=PUNIT )
> private static EntityManagerFactory emf;
>
> private static final EntityManagerFactory EMFCANON =
> Persistence.createEntityManagerFactory( PUNIT );
>
> public static EntityManagerFactory getEmf()
> {
> return (emf == null? EMFCANON : emf);
> }
> }
>
> For the manager:
> <http://java.sun.com/javaee/5/docs/tutorial/doc/bnbrm.html#bnbrp>
>
> public class Bizzniss
> {
> @PersistenceContext
> private EntityManager em;
>
> public void run()
> {
> EntityManager mgr = (em != null? em
> : Persistuff.getEmf().getEntityManager());
> // use 'mgr' here
> }
> }
>
> Unknown: resource consumption and packratting caused by injected values,
> if any.


I wouldn't bother to do the above, but in response to Tom's question the
above is what I would do. If that makes any sense.

After all, there are no classpath issues - Java knows about the
annotations. All that happens, from observation, is that if in a given
situation that injection doesn't work then it doesn't work, and you
proceed and use the other approach(es).

My gut feeling is that if injection doesn't work then there's not much
penalty. For example, if your version of JSF doesn't support specific
annotations then nothing happens when you inadvertently use them.

I simply haven't bothered doing anything like the above because I never
write J2EE apps where it's not already known exactly what the
environment is. And if the environment ever changes there'll be major
advance notice.

> Learning how to do this, I was running Glassfish 3 with a Postgres back
> end, but my 4 GB RAM server box's power supply just gave up the ghost.
> Turns out the combination of GF and PG with NetBeans was too much for my
> poor single-core 64-bit workstation with only 1 GB RAM. Then I tried
> the non-injective approach with Tomcat, Postgres and NetBeans. Turns
> out that runs just great on the workstation.
>
> That triggered a major "Hmmm." I may be on to a way to develop, deliver
> and deploy full-blown custom apps very quickly with very low
> administrative and hardware overhead.
>
> Looks like JSF, JSP, JPA and servlets on Tomcat are a winning
> combination. Once you factor in a few quirks.
>
> (Bonus - Tomcat plays well with other environments like Apache Web
> Server and many Java EE application servers.)


We ourselves (me and the other folks at the small consulting company I
work for) have internally arrived at much the same conclusion. As in,
why bother with a full-fledged app server when you don't need it?

To your list of API's/frameworks I would also add Seam as a
consideration, for some projects.

AHS
 
Reply With Quote
 
Tom Anderson
Guest
Posts: n/a
 
      08-12-2009
On Tue, 11 Aug 2009, Lew wrote:

> Tom Anderson wrote:
>> Is there a convenient way to write code that gets an injected EntityManager
>> in a managed environment, but arranges its own provision in an unmanaged
>> one? Is that a meaningful thing to ask for?

>
> I have a way, but I won't know if it works until I succeed at getting an
> injected one. Then I can compare the two scenarios.
>
> For the factory:
>
> public class Persistuff
> {
> public static final String PUNIT = "projectPU";
>
> @PersistenceUnit( unitName=PUNIT )
> private static EntityManagerFactory emf;
>
> private static final EntityManagerFactory EMFCANON =
> Persistence.createEntityManagerFactory( PUNIT );
>
> public static EntityManagerFactory getEmf()
> {
> return (emf == null? EMFCANON : emf);
> }
> }
>
> For the manager:
> <http://java.sun.com/javaee/5/docs/tutorial/doc/bnbrm.html#bnbrp>
>
> public class Bizzniss
> {
> @PersistenceContext
> private EntityManager em;
>
> public void run()
> {
> EntityManager mgr = (em != null? em
> : Persistuff.getEmf().getEntityManager());
> // use 'mgr' here
> }
> }


Do you need the injection bits in Persistuff? If injection is working,
Bizzniss will get an EntityManager of its own, and never have to call
Persistuff.getEmf(). The only time it will have to call it is when there
is no injection, in which case the injected in field in Persistuff will be
null anyway. I suppose this approach means you take advantage of the case
where a EntityManagerFactory is injected but a PersistenceContext isn't.
That seems like a bit of an unlikely case to me, but i am far from an
expert on this.

> Unknown: resource consumption and packratting caused by injected values, if
> any.


True that.

> Learning how to do this, I was running Glassfish 3 with a Postgres back end,
> but my 4 GB RAM server box's power supply just gave up the ghost. Turns out
> the combination of GF and PG with NetBeans was too much for my poor
> single-core 64-bit workstation with only 1 GB RAM. Then I tried the
> non-injective approach with Tomcat, Postgres and NetBeans. Turns out that
> runs just great on the workstation.
>
> That triggered a major "Hmmm." I may be on to a way to develop, deliver and
> deploy full-blown custom apps very quickly with very low administrative and
> hardware overhead.


I'm surprised GF took *so* much extra memory (and CPU?). What's it doing?

Are there any lightweight app servers that wouldn't be a big overhead over
Tomcat (or perhaps even better, Jetty)?

tom

--
SAWING CHASING CRUNCHING ROBOTIC DEMOLITION
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      08-12-2009
Lew wrote:
>> Learning how to do this, I was running Glassfish 3 with a Postgres
>> back end, but my 4 GB RAM server box's power supply just gave up the
>> ghost. Turns out the combination of GF and PG with NetBeans was too
>> much for my poor single-core 64-bit workstation with only 1 GB RAM.
>> Then I tried the non-injective approach with Tomcat, Postgres and
>> NetBeans. Turns out that runs just great on the workstation.
>>
>> That triggered a major "Hmmm." I may be on to a way to develop,
>> deliver and deploy full-blown custom apps very quickly with very low
>> administrative and hardware overhead.


Tom Anderson wrote:
> I'm surprised GF took *so* much extra memory (and CPU?). What's it doing?
>
> Are there any lightweight app servers that wouldn't be a big overhead
> over Tomcat (or perhaps even better, Jetty)?


In part the answer depends on how much app server you need. Tomcat already is
an app server for web apps and web services. Arved's suggestion of Seam
<http://www.jboss.com/products/seam/>
seems promising.

Do you need EJBs? Tomcat with Apache OpenEJB might do the trick. Seam does
that, too. One day I'll test to find out, if I can figure out why I ever need
EJBs.

Do you just need dependency injection? Maybe Spring is enough (or too much -
I'm still deciding).

Do you need message queues? BPEL? Integrated JNDI? Multiple cooperating
apps or quasi-independent components? Common services for multiple enterprise
applications? Clustering or other scalability strategies?

My untested hypothesis is that there's a threshold of system complexity or
performance where the overhead of a full-blown app server like JBoss or
Glassfish is less than the difficulty of managing or scaling piecemeal solutions.

If nothing else, there's the fact that the job market requires practitioner
skill in all of that, so it behooves me to buy a new power supply for my
multi-core PC and keep practicing with full-bore Java EE.

--
Lew
 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      08-14-2009
On 12.08.2009 16:06, Lew wrote:

> My untested hypothesis is that there's a threshold of system complexity
> or performance where the overhead of a full-blown app server like JBoss
> or Glassfish is less than the difficulty of managing or scaling
> piecemeal solutions.


I second that. That bad news is

1. it's difficult to determine that level of complexity

2. from my experience real world software tends to start out simple and
ends up complex

So it's probably worthwhile to consider going full JEE earlier than you
really need it.

Unfortunately those JEE containers do also have issues of their own.
The fact that JBoss introduces the third transaction manager in a
relatively short period of time gives you hints as to where they might
lie. A pity TX management is so fundamental...

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
JPA, Oracle and stored procedures Curtis Java 4 06-26-2007 01:53 PM
JPA Implementations info@apsquared.net Java 0 05-13-2007 02:23 PM
Databases have views, JPA has nothing equivalent :/ josh Java 0 02-26-2007 08:17 PM
A implicit @Id for JPA for pure POJO ? Vincent Cantin Java 0 12-24-2006 04:47 PM
Remember when your piano teacher taught you, "Practice, practice,practice ...?" Wayne Wastier Windows 64bit 3 06-10-2005 08:29 PM



Advertisments