Skip to main content

@PersistenceContext in JSF managed bean--how?

12 replies [Last post]
cayhorstmann
Offline
Joined: 2003-06-13

I just read http://weblogs.java.net/blog/edburns/archive/2006/02/new_drafts_of_j_1.html

The blog says that the JSF spec has been updated--you can now use @PersistenceContext in a JSF bean. The blog also says that this is fully implemented in b37.

I tried it, and I got this error message:

javax.servlet.ServletException: Unable to retrieve EntityManagerFactory for unitName defaultPersistenceUnit

Actually, I was curious how this would work. A JSF managed bean does not live inside the EJB container, right? So I tried the approach outlined in https://glassfish.dev.java.net/javaee5/persistence/persistence-example.html and used @PersistenceContext instead. Same error.

Ok, maybe it can't find persistence.xml? Here I am getting fuzzy on the deployment rules. I deploy an ear file that contains an ejb.jar file and a web.war file. I guess the JSF stuff inside web.war can't find ejb.jar. (Well, that can't quite be the answer--the same setup is perfectly willing to inject sessions beans into JSF manageed beans.)

I am left with two questions. (1) Can I really use the entity manager in JSF managed beans and bypass session beans altogether? (2) How should I organize my deployment archive?

Thanks,

Cay

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ss141213
Offline
Joined: 2005-03-30

Hi Cay,

[u]packaging of persistence units:[/u]

a persistence unit (PU) can be defined either in [b]ear scope[/b] or in [b]module[/b] (ejb/war/appclient jar) scope. When it is defined in ear scope, it is visible to all the modules in the application. When it is defined in module scope, it is [b]private[/b] to that module. To define a PU in the ear scope, it has to be put in a library jar file in ear file. The easiest way to do this is to put your entities.jar in ear lib directory.

[u] why ear and not war?[/u]
Since you are using both ejbs and web modules, you have to use an ear file to package them together. Putting ejb-jar inside war/WEB-INF/lib does not work because container is going to treat that file as another library jar file.

[u] can I access entity beans without using ejbs?[/u]
Yes you can. See http://weblogs.java.net/blog/ss141213/archive/2005/12/introduction_to.html where such an example is available. using JSF in your web application is no different.

[u] why did I have lib/ejb-interfaces.jar in my blog example?[/u]
You mentioned that you did not have to separate ejb-interface classes to a separate jar file and things worked. Well that is not a portable way to package. Try running [i]verifier -p myapp.ear[/i]. You shall see that it will complain about your servlet using some classes that are not available. Even though sessions.jar and web.war are inside myapp.ear, a container may have two independent class loaders for each module and sessions.jar may not be available to web.war. That's the reason I put entities.jar and ejb-interfaces.jar in lib directory. All jars in [b]lib[/b] directory are automatically available to all modules.

[u]duplicate classes[/u]
Finally, you mentioned about some [b]duplication[/b] of classes in my blog example. May I know where classes are duplicate in that example? I thought, I had specifically tried to avoid any kind of duplication in the packaging I proposed at http://weblogs.java.net/blog/ss141213/archive/2005/12/using_java_pers.html

If you happen to run verifier, then be aware of a known regression( https://glassfish.dev.java.net/issues/show_bug.cgi?id=245 ) at this point of time.

Thanks,
Sahoo

dibyendumajumdar
Offline
Joined: 2005-01-15

Sahoo,

I am using a similar structure as Cay - ie, I put the session beans outside the lib folder. I ran the verifier and it did not complain.

I guess to see the effect of the placement of the jar files, we need two separate EJB modules and try invoking beans in one module from beans in another. I will try this out and see what happens.

Regards

Dibyendu

ss141213
Offline
Joined: 2005-03-30

> I am using a similar structure as Cay - ie, I put the
> session beans outside the lib folder.

I didn't understand what you meant by putting session beans outside lib folder.

> I ran the verifier and it did not complain.

Did you use [b]-p[/p] option in verifier? That option is the portable mode of verifier. By default verifier runs in GlassFish mode where it allows you to package things the way GlassFish accepts. A portable app will run inside GlasFish, but not necessarily the other way around.

>
> I guess to see the effect of the placement of the jar
> files, we need two separate EJB modules and try
> invoking beans in one module from beans in another. I
> will try this out and see what happens.

Not necessary.
The following is an example of non-portable packaging:

ear/
ejb.jar
web.war // web.war is a client of the ejb.

[b]unless[/b] web.war uses Class-Path manifest entry pointing to ejb.jar. This will work in GlassFish, but it's non-portable.

Thanks,
Sahoo

>
> Regards
>
> Dibyendu

dibyendumajumdar
Offline
Joined: 2005-01-15

> Did you use [b]-p[/p] option in verifier? That option
> is the portable mode of verifier. By default verifier
> runs in GlassFish mode where it allows you to
> package things the way GlassFish accepts. A portable
> app will run inside GlasFish, but not necessarily the
> other way around.

Yes, I am using the -p option.

Regards

ss141213
Offline
Joined: 2005-03-30

Hi Dibyendu,

> Yes, I am using the -p option.

Interesting. Can you send me your app to take a look at it? I want to rule out the possibility of a bug in verifier. Either you can create an issue and attach the app there or send me an email.

Thanks,
Sahoo

dibyendumajumdar
Offline
Joined: 2005-01-15

> Interesting. Can you send me your app to take a look
> at it? I want to rule out the possibility of a bug in
> verifier. Either you can create an issue and attach
> the app there or send me an email.

Sahoo,

You can access the stuff from:

https://ejb3demo.dev.java.net/files/documents/4648/29111/ejb3demo-230206...

The project to look at is called tpcc-ea.
If you run ant verify - it should run the verifier.
Note that the Glassfish installation is expected to be at c:\glassfish.

Thanks

ss141213
Offline
Joined: 2005-03-30

Hi Dibyendu,

I found a bug in verifier. I have added you to the CC list of the newly filed issue:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=298

Thanks for sending your application.

On a separate note, some of your build.properties files do not define libs property. The ones that defines them, uses ; as file separator. So you may like to address them. Any way, I worked around them.

Sahoo

cayhorstmann
Offline
Joined: 2003-06-13

Hi Sahoo,

thanks for your clarifications and my apology for the late reply. The duplication in your blog at http://weblogs.java.net/blog/ss141213/examples/blog5.zip was the class file UserCredentialManager.class that occurred both in ejbs.jar and ejb-interfaces.jar.

Is that actually necessary? I seem to have been successful with this arrangement:

session-impls.jar
web.war
lib/session-intf.jar
lib/entities.jar

No duplication was necessary. Then again, GlassFish might be smarter than the standard requires. Where exactly does the spec describe the visibility rules?

Thanks,

Cay

ss141213
Offline
Joined: 2005-03-30

> Hi Sahoo,
>
> thanks for your clarifications and my apology for the
> late reply. The duplication in your blog at
> http://weblogs.java.net/blog/ss141213/examples/blog5.z
> ip was the class file UserCredentialManager.class
> that occurred both in ejbs.jar and
> ejb-interfaces.jar.
>
> Is that actually necessary?
No, not at all necessary. I never intended it that way. It has to be a bug in my build.xml. If you see that example, I package ejb-interfaces.jar in lib dir, so there is no reason for that class to be in ejbs.jar.

> successful with this arrangement:
>
> session-impls.jar
> web.war
> lib/session-intf.jar
> lib/entities.jar
>

This is the recommended way. You got it right.
> No duplication was necessary. Then again, GlassFish
> might be smarter than the standard requires. Where
> exactly does the spec describe the visibility rules?
>

Read Java EE platform spec (http://jcp.org/aboutJava/communityprocess/pfd/jsr244/index2.html), cha[ter #8.

Thanks,
Sahoo

cayhorstmann
Offline
Joined: 2003-06-13

I just tried a different setup. I deploy a WAR with the following organization:

JSF pages
WEB-INF/classes/managed beans
WEB-INF/lib/ejb.jar (with persistence.xml in META-INF)

Now I no longer get the error about a missing persistence context. The EntityManager (or EntityManagerFactory) is simply null. No injection is happening at all.

I looked at Sahoo's example in http://weblogs.java.net/blog/ss141213/archive/2005/12/using_java_pers.html. It seems quite a bit more complex, with some class files duplicated. Before I try that, I have a simple question:

Is deploying a WAR file inherently futile if I want to get EJB3 features injected in my JSF managed beans? (I.e. do I have to package the WAR inside an EAR)?

Thanks,

Cay

cayhorstmann
Offline
Joined: 2003-06-13

Well, I finally got something to work. I follow a simplified version of Sahoo's packaging approach in http://weblogs.java.net/blog/ss141213/archive/2005/12/using_java_pers.html.

1. Use an EAR, not a WAR--otherwise, stuff isn't happening on the app server upon deployment. (Is that right?)
2. No need to use application.xml
3. Put an entities.jar inside lib. That way, the web app can see the persistence unit.
4. Put a sessions.jar outside lib--otherwise, the app server won't register the session beans in JNDI (Is that right?)
5. Put the web stuff in a WAR.

myapp.ear:
META-INF/ <-- no application.xml needed
lib/entities.jar <-- contains persistence.xml
sessions.jar
web.war

Sahoo separates out a jar file for the session bean interfaces and places that in the lib directory as well. It makes sense that you should do that, but for some reason I didn't have to deal with it. The code inside web.war was able to see the classes in sessions.jar.

I wish I really understood the packaging rules.

Cay

ss141213
Offline
Joined: 2005-03-30

Hi Cay,

[u]packaging of persistence units:[/u]

a persistence unit (PU) can be defined either in [b]ear scope[/b] or in [b]module[/b] (ejb/war/appclient jar) scope. When it is defined in ear scope, it is visible to all the modules in the application. When it is defined in module scope, it is [b]private[/b] to that module. To define a PU in the ear scope, it has to be put in a library jar file in ear file. The easiest way to do this is to put your entities.jar in ear lib directory.

[u] why ear and not war?[\u]
Since you are using both ejbs and web modules, you have to use an ear file to package them together. Putting ejb-jar inside war/WEB-INF/lib does not work because container is going to treat that file as another library jar file.

[u] can I access entity beans without using ejbs?[/u]
Yes you can. See http://weblogs.java.net/blog/ss141213/archive/2005/12/introduction_to.html where such an example is available. using JSF in your web application is no different.

[u] why did I have lib/ejb-interfaces.jar in my blog example?[\u]
You mentioned that you did not have to separate ejb-interface classes to a separate jar file and things worked. Well that is not a portable way to package. Try running [i]verifier -p myapp.ear[/i]. You shall see that it will complain about your servlet using some classes that are not available. Even though sessions.jar and web.war are inside myapp.ear, a container may have two independent class loaders for each module and sessions.jar may not be available to web.war. That's the reason I put entities.jar and ejb-interfaces.jar in lib directory. All jars in [b]lib[/b] directory are automatically available to all modules.

[u]duplicate classes[/u]
Finally, you mentioned about some [b]duplication[/b] of classes in my blog example. May I know where classes are duplicate in that example? I thought, I had specifically tried to avoid any kind of duplication in the packaging I proposed at http://weblogs.java.net/blog/ss141213/archive/2005/12/using_java_pers.html

If you happen to run verifier, then be aware of a known regression( https://glassfish.dev.java.net/issues/show_bug.cgi?id=245 ) at this point of time.

Thanks,
Sahoo