|
|
||
Sahoo's BlogJ2EE ArchivesA javac plugin to manage your persistence.xmlPosted by ss141213 on November 26, 2007 at 07:54 AM | Permalink | Comments (3)I am glad to say that in most cases, I do not write a persistence.xml file any more. No, I am not using any IDE to generate it for me, nor has the spec relaxed any requirement. We will discuss some other time why persistence.xml is a necessary evil. Then what has changed? Well, my compiler creates it for me - yes, I said javac creates it for me. When I execute No, I have not modified javac. Starting with Java SE 6, the Java Compiler allows users to plug in an annotation processor which gets called in an appropriate phase of compilation. If an annotation processor is available in javac's classpath, then javac can discover it using service discovery mechanism. Read Annotation Processing in javac for further information. Using the said feature, I have written a simple, standard compliant javac plugin to provide the necessary functionality. How you can use? For command line javac invocation, just add it to compiler classpath using -classpath option. e.g., Maven users: < dependency> That's it, no other change is needed. Isn't it straight forward to use? How to pass additional options to the plugin: Conclusion: Welcome to GlassFish @ FOSS.IN 2006Posted by ss141213 on November 23, 2006 at 09:00 AM | Permalink | Comments (2)GlassFish at FOSS.IN 2006 Highlights of the demo: What does the demo app do? Important Links: See you in GlassFish presentation and booth at FOSS.IN. More blogs about GlassFish Persistence Context propagationPosted by ss141213 on October 27, 2006 at 11:01 AM | Permalink | Comments (17)What is persistence context propagation? Rules governing PC propagation 2. A PC is propagated along with the JTA transaction. 3. PC propagation is applicable only to local environments(i.e. one JVM). PC is not propagated across remote tiers even if the remote component is collocated in the same address space as the client. 4. A PC is propagated when the called component uses EM that belongs to the same Entity Manager Factory as the caller. 5. It is an application error to attempt to propagate a PC to a SFSB that is already associated with a different PC. In such a case, EJB container throws EJBException to the caller. Let's apply the rules (rule shown in ()) and see some cases where PC propagation takes place: 1. (rule #1) Since a container managed EM can only be obatined via @PersistenceContext or persistence-context-ref, PC propagation does not take place for EMs obtained using EntityManagerFactory.createEntityManager(). 2. (rule #2) A PC won't be propagated (e.g.) when an EJB with bean managed transaction or an EJB method with transaction attribute REQUIRES_NEW, NOT_SUPPORTED or NEVER is called because transactions are not propagated to such methods(see Chapter #13 of EJB 3.0 Core specification). More over, unless the caller is associated with a transaction, PC propagation will not happen. I don't know the behavior when a request is dispatched from one web component to another using using RequstDispatcher object. There are two questions that determine the answer, viz: a) is that ever considered a local call? b) does web container propagates the JTA transaction along with the request? If you know the answer, let me know. Else, I will try to find out myself. 3. (rule #3) Don't expect PC to be propagated when you call a remote EJB even when the remote EJB happens to be running in the same JVM or part of the same application. 4. (rule #4) All the components that want to share the PC must use the same persistence unit. Container internally creates an EntityManagerFactory corresponding to a persistence unit and uses it to create EMs. Persistence units defined in separate persistence.xml files or persistence units defined separately in one persistence.xml file are considered different no matter how idenically they are set up. So, if components from two different modules in an EAR file (e.g. a Servlet calling an EJB) want to share PC, then the persistence unit must be packaged as an EAR scoped persistence unit (e.g. in a jar file in lib folder of the EAR). 5. (rule #5) If a component is associated with a PC then it can't call a local SFSB with a different extended PC to which current transaction context will be propagated. GlassFish reports this very nice message when I tried doing this in a test case: javax.ejb.EJBException: There is an active transactional persistence context for the same EntityManagerFactory as the current stateful session bean's extended persistence context. (rule #5) These rules are not complete. Please refer to the JPA spec for more details. 1. ReportServlet.java
The above look up returns a valid EM because the Servlet has declared a dependency on a PC for the persistence unit named pu1 and has given this dependency a name persistence/EM1 using the following code:
ReportServlet begins a transaction using the injected UserTransaction object, obtains a managed entity instance by invoking lookup method of injected UserCredentialManager session bean, accesses the lazily fetched field of the entity and then commits the transaction in the code below:
2. UserCredentialManagerBean.java: 3. Persistence Unit: You may have noticed that ReportServlet does not use the EM in any meaningful way. So, it can be totally removed from ReportServlet and yet ReportServlet will be able to use the entity in the same PC as that of the EJB. Let's see what would have happened if ReportServlet does not start the transaction before calling lookup method. Lookup method starts a new transaction and EJB container creates a new PC when the injected EM is used. This PC gets closed automatically when the transaction is ended at the end of that method, thus the returned entity becomes detached. Since fetch type for loginAttempts is LAZY (by default it is lazy for collection valued fields) and the field has not been accessed by lookup method, accessing it in the Servlet is asking for trouble (see section #3.2.4 of the JPA spec). GlassFish persistence provider is generous enough to allow such an access, but when I tested using OpenJPA, it threw a NullPointerException. Conclusion Resources Using OpenJPA as Java Persistence API provider in GlassFishPosted by ss141213 on July 27, 2006 at 03:31 PM | Permalink | Comments (6)As this theserverside.com announcement shows, although OpenJPA is still in the Apache incubator and not yet certified as a Java Persistence API compliant provider, it is not far from that stage. There is a source download available and I must say, it is quite easy to build. If you want to use it in GlassFish, then it's even easier. It is as simple as these intuitive steps:
cp ${OPENJPA_HOME}/openjpa*.jar ${OPENJPA_HOME}/lib/*.jar ${GLASSFISH_HOME}/domains/domain1/lib GlassFish will automatically make this jar part of its classpath next time when you restart the server.
Step #5: Build and deploy your app
Having said that, you actually don't need to copy the following jar files as GlassFish runtime already have those classes: Hope you find this blog useful. More blogs about glassfish persistence Thanks. Using Kodo as Java Persistence API provider in GlassFishPosted by ss141213 on May 28, 2006 at 03:44 AM | Permalink | Comments (2)Earlier we had shown how to plug in Hibernate in GlassFish. Now it's time for Kodo, which is another high performance & popular O/R mapping solution. Recently Kodo 4.0GA was released and it supports Java Persistence API 1.0. So, I thought I shall give a try using it in GlassFish. The instructions are really simple. They do not involve any unreasonable steps. Step #1: Download and install GlassFish Step #2: Download and install Kodo 4.0GA Step #3: Install Kodo in GlassFish cp $KODO_HOME/lib/kodo.jar $GLASSFISH_HOME/domains/domain1/lib/ GlassFish will automatically make this jar part of its classpath next time when you restart the server. Step #4: Edit persistence.xml Step #5: Build and deploy your app Points to note: 2. We can use Java2DB feature of GlassFish even while using Kodo. In fact, example #2 uses this. This feature is very handy for folks who don't have a prexisting database schema to work with. Which GlassFish build to use? bug #679: This affects web applications using Java Persistence API. As a work around, you have to package enhanced classes in your web application. Kodo comes with a program called kodoc which you can use to enhance the classes. I have already fixed this bug in GlassFish v2 and it will be available in GlassFish v2 build #04. Until build #04 is available, you can download the latest GlassFish v2 nightly build and use. bug #233: It affects EJBs using Java Persistence API. As a work around, you have to redeploy the application every time you start the server. I have a fix available in my local workspace which I am going to integrate very soon in GlassFish v2 (most likely, it shall be part of v2 build #04). Conclusion: Which GlassFish build to use?Posted by ss141213 on May 05, 2006 at 01:45 AM | Permalink | Comments (3)Looking at some of the recent postings in the GlassFish forum, there appears to be some confusion in the GlassFish user community about which build to use. I will try to address the issue in this blog. The main reason for this confusion is due to presence of two very active branches in the GlassFish CVS repository, viz: SJSAS90_FCS_BRANCH and the trunk (a.k.a. the main branch). They look something like this:
As the name suggests, SJSAS90_FCS_BRANCH is used for release of Sun Java System/Application Server PE 9.0 as well as Java EE 5 SDK. As the diagram shows, this branch was forked from the trunk around 30 March 2006. It is a highly controlled branch as it is used to release a product and currently this branch is in high resistance mode as the final release date is fast approaching. As a standard product release process, not all kinds of bug fixes are going into this branch. The situation is very different for the trunk. It is open for checkins. In fact a lot of bug fixes and quite a few enhancements have gone into the trunk since SJSAS_90FCS_BRANCH was forked. If I have to single out any one module which has changed most in the trunk since the 9.0 branch was forked, then it will be entity-persistence module, which is the Java Persistence API implementation module in GlassFish. Not all these fixes were back ported to the SJSAS_90FCS_BRANCH for obvious reasons. Be rest assured, a number of these bugs will eventually be made available in a subsequent Update Release(UR) for 9.0. Difference between promoted builds and nightly build Build Numbers/Name: What is the confusion? Finally, there is no promoted builds happening on the trunk right now. If you look at the GlassFish promited builds download site, you can see that after b42, there are no promotions happening on the trunk. Only nightly builds are happening as GlassFish nightly build download site shows. If you choose the platform of your choice there, you can see that there are download bundles are available with names like glassfish-installer-b43-nightly-01_may_2006.jar. Look at the date encoded in the name. That conveys the date on which that binary was built. When is situation going to improve? Conclusion Using Java Persistence API in application client in Java EE platformPosted by ss141213 on March 21, 2006 at 01:03 AM | Permalink | Comments (7)In Java EE 5 platform Java Persistence API can be used in three types of containers, viz: ejb, web and application client container. In my earlier blogs, I had talked about using this API in web applications and in EJB applications. This time we will talk about using Java Persistence API in application clients. We also discuss about two different way of packaging the application. You can download the complete sample, unzip and run 'ant deploy' to see the sample in action. The steps are very simple as discussed below: Step #1: Write entity bean UserCredential.java Step #2: Define a persistence unit in persistence.xml <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> Points to note about this persistence.xml are: 1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name pu1. 2) We need not specify any elements/attributes other than transaction-type, as the default values are just fine. By default the entity manager's transaction type is JTA. Since Application Client Container is not required to support JTA, we can not use JTA entity managers in this example. So we have set it to RESOURCE_LOCAL here. 3) There is no need to enumerate all the entity bean class names inside because we are defining only one PU in this persistence.xml and we will be packaging the entity classes along with this persistence.xml in a jar file, so container can discover all the entity beans. Step #3: Write Client.java 1) It declares dependency on the PersistenceUnit using @PersistenceUnit as shown below: @PersistenceUnit private static EntityManagerFactory emf; Also note that, the field ucm is static. More discussion on this further below. Secondly, there is only one PU visible to this application client, hence there is no need to specify the unitName attribute in @PersistenceUnit. 2) It must be a public class because it will be used by ACC which does not belong to the package of this class. 3) We also need to write a manifest.mf file which must contain the name of the class containing the main(). 4) The rest of the client class is simple. It creates an EntityManager using the injected EntityManagerFactory. It closes it at the end of the application. Since we can't use JTA, the client uses EntityTransaction API to manage transactions. 5) There is no need to write application-client.xml because it is optional. Java EE 5 compatible platform can discover appclient.jar's module type because it contains META-INF/MANIFEST.MF with a Main-Class attribute. Step #4: Build and package the application using build.xml jpa_acc_option1.ear Since the entities.jar is placed in the EAR lib directory, it is automatically added to CLASSPATH while running the appclient. So, no need to use Class-Path manifest entry. Option #2: package the entity beans and the persistence.xml in the appclient.jar along with appclient main class. No need to make an ear file in this case, as we can just deploy the appclient.jar. The appclient.jar contains following entries: appclient.jar: To demonstrate this, there are two build targets, viz: build-app1 and build-app2. The third build target internally call these two targets. Same goes for deploy and verify targets. Both of the packaging alternatives discussed here are completely portable. It is upto you to decide which of the options you want to use. Step #5: Run the application Use of Java2DB Why injected field or method must be static in application client? Software Required Hope you found this example useful. More examples of glassfish persistence When can I use hibernate as EJB3 persistence provider in GlassFishPosted by ss141213 on January 17, 2006 at 01:08 AM | Permalink | Comments (5)Can I use Hibernate in GlassFish? is a question I have been asked several times in recent past? Well, the answer is Yes & No(as of now), depending on what you are trying to use it as. By the way I must clarify, it's a NO only temporarily. Let's understand why: Yes: No: EJB 3.0 Persistence SPI Some EJB 3.0 Persistence API related resources: Introduction to using Java Persistence API in Java EE More articles about glassfish persistence Custom tags to use Java Persistence API in JSPPosted by ss141213 on January 02, 2006 at 12:57 PM | Permalink | Comments (0)In earlier articles we have discussed about using Java Persistence API in a web application and in a multi-tier Java EE application. In this article I shall talk about a few custom JSP tags (the links in that page are broken, but when you download the complete bundle it includes a page where links work.) that I have developed to use Java Persistence API in JSPs. Collectively the tags are referred to as jpa taglib here. It also shows how to inject persistence context into JSPs. A JSP tag library is a collection of custom tags where each tag abstracts out some functionality used by a JSP page. Not only allows a more natural use of that functionality within JSP pages, but also it allows separation of responsibilities. Source code for the tag library and a sample web application that illustrates the use of the tag library as well as the binaries are available here. Downloaded bundle also include documentation about the tag library that is generated using tlddoc. Detailed Steps: Step #1: Write custom tags A tag library is a collection of tags. Prior to JSP 2.0, custom tags could only be developed using Java language, but JSP 2.0 allows custom tags to be developed using an Expression Language. I am using Java to develop custom tags. The source code for the tags are in jpa-tag-lib/src directory in package com.sun.jpatl package. of all the tags, jpa:tx tag is TryCatchFinally kind of tag. It is written such that it always ends the transaction, in case of no exception in the embedded JSP fragment, it commits the tx, else it rolls back the tx. All other tags are Simple Tags. Step #2: Write a tag library descriptor jpa.tld A tag library descriptor is an XML document describing the tags that are part of the library. Refer to the JSP Spec fpr mode details. As you can see from the tld file, I have given the URI as http://weblogs.java.net/ss141213/tags/jpa. The tag classes along with tag library descriptor file(jpa.tld) are packaged in a file called jpa-tag-lib.jar which is bundled in WEB-INF/lib dir of the web application. Step #3: Write a sample web application that uses jpa-tag-lib Let's write a simple web application that uses these tags to do some database operation. The functionality of this web application is same as the one described in my earlier blog. Step #3.1: Write entity bean UserCredential.java Step #3.2: Define a persistence unit persistence.xml The entity classes along with persistence.xml are packaged in entities.jar which is bundled in WEB-INF/lib dir of the web application. Step #3.3: Write login.jsp Points worth noting about this JSP are: <%@ taglib uri="http://weblogs.java.net/ss141213/tags/jpa" prefix="jpa" %> 2) It uses custom tag called jpa:injectDefaultPC to inject a container managed entity manager. This entity manager instance is made available in a variable called em1. 3) It uses custom tag jpa:find passing it the entity manager that was earlier injected. Also note how it uses a request time expression to pass the value of the primary key. The searched object is stored in a variable called credential which is later on used by the JSP to compare password. Step #3.4: Write registration.jsp Points worth noting about this JSP are: 1) It uses jsp:useBean to initialise a bean called credential by reading attributes passed in request object. 2) It uses custom tag jpa:tx to mark the boundary of a transaction. Inside this transaction, it uses uses custom tag jpa:persist to persist the java bean. Step #3.5: Write a couple of html files called login.html and registration.html. Note, there is no need to write any web.xml as it is optional in Java EE 5. Step #4: Build using build.xml This is a very simple build.xml just to demonstrate the compilation and packaging process. The build targets are: The last three targets are specific to Sun Java System Application Server 9 PE which is implementing Java EE 5 spec. As you can see, to compile the sources, only library needed is javaee.jar which contains the Java EE 5 platform APIs. Step #5: Set up a data source By default in glassfish entity manager uses the default pre-configured data source with JNDI name jdbc/__default that glassfish comes with. This data source talks to a Derby database called sun-appserv-samples. Refer to the README where I have listed the command needed to start and stop the Derby database. Glassfish has a feature called Java2DB which can autocreate the database schema during deployment, so there is no need to create tables. Step #6: See them in action Want to help? This is my first attempt to write a tag library, so comments are most welcome. I plan to enhance the tag library and make them available in future. I am even thinking of starting an open source effort to make a production quality tag library for Java Persistence API. Interested readers are welcome to join me in this effort. References: Java Server Pages More articles about glassfish persistence jsp. Don't use @PersistenceContext in a web app...Posted by ss141213 on December 19, 2005 at 12:18 PM | Permalink | Comments (9)I wrote an example web application that uses Java Persistence API. My servlet code looked like this: public class RegistrationServlet extends HttpServlet {
This code worked, but only by chance. I did not realize that I have committed a horrible mistake in my servlet code. As the servlet spec suggests, unless explicitly mentioned in the deployment descriptor (web.xml) as SingleThreadModel, a single servlet instance by default can be shared to serve multiple requests concurrently. i.e. multiple threads can simultaneously enter the service() method of our servlet because we have not marked the service() as synchronized. As a result multiple threads will share the same PersistenceContext object via the instance variable em. A persistence context is not required to be thread safe as per the spec and is typically designed not to be used concurrently. Because the behavior is timing dependent and I had a tiny example, I did not see this issue during testing. What is the fix If we can't use @PersistenceContext to inject an EntityManager, what is the fix? The fix is to either Container Managed Entity Manager @PersistenceContext(name="persistence/LogicalName", unitName="ActualPUNameAsItAppearsInPersistence.xml") Note that there is no injection going on here since the annotation @PersistenceContext appears at the class level. This is an alternative to declaring the persistence context dependency via a persistence-context-ref in web.xml as discussed below (in option #b). b) via persistence-context-ref in web.xml In web.xml, add an element like this: < persistence-context-ref> Now do a JNDI lookup in your code as shown below: public class RegistrationServlet extends HttpServlet {
While using container managed entity manager (whether option #a or #b is used), we did not call em.close() because container is managing the life cycle of underlying persistence context. We also did not have to call utx.rollback() because web container would automatically rollback a transaction at the end of http request processing if servlet does not end the tx. Application Managed Entity Manager public class RegistrationServlet extends HttpServlet {
See we call close() to close the EntityManager. More over note the use of try catch finally block. Since em.close() can not be called as long as the associated transaction is complete either by calling commit() or rollback(), we have to write those try catch finally. Is it mentioned any where in the spec? In Transaction Management chapter, section #4.2.3 of Java EE 5 proposed final draft spec, it is mentioned that: In web components not implementing SingleThreadModel, transactional resource If you want to draw an analogy with JDBC world then EntityManager is like a Connection, where as EntityManagerFactory is like a DataSource. So EntityManager (or a PersistenceContext) which is a transactional resource should not be stored in a instance field and hence should not be injecte into a web app that does not implement SingleThreadModel.EntityManagerFactory is thread safe, so it can be injected into the servlet. What is the performance over head? Creation of a EntityManagerFactory is typically a costly operation. But creation of EntityManager is not. So creating an EntityManager is inside service() does not have negative impact on performance. What about thread safety of UserTransaction? If you see the code above, it still injects a UserTransaction object and stores in an instance field. That is not issue because it is a stateless object and can be shared across multiple threads. Looking at the javadocs for UserTransaction, it is clear that it by itself does not represent the transaction object, instead it is an interface to the underlying transaction manager to begin a new transaction and associate that with current thread; and end a transaction associated with current thread. More articles about glassfish persistence. Using Java Persistence API in Java EE Platform - Part IIPosted by ss141213 on December 15, 2005 at 08:59 AM | Permalink | Comments (17)The Java Persistence API is the standard API for the management of persistence and object/relational mapping in Java EE 5 platform. Every Java EE 5 compatible application server will support this API. Earlier I had written about how to use Java Persistence API in a web application. This time I shall extend the example to include EJBs and application client so that we have a multi-tier (web->ejb->db and appclient->ejb->db) Java EE app. The focus of this exercise is to show how simple it is to develop such complex multi-tier Java EE application in a portable way. We will see how to package such an application so that it is not only portable, but also efficient. It uses the library directory facility to package common classes. In the process we shall see various injections like @EJB and @PersistenceContext in use. Like last time, I will not use any kind of IDE because Java EE 5 is Easy to Use. More over IDEs tend to do things behind the screen and that hampers learning. Because of the walkthrough nature of this article, it's to be a long one, but don't get overwhelmed by the size! At each critical step , I shall try to explain why certain things are done the way they are. If you are impatient, you can download the complete sample, unzip and run 'ant deploy' to see the sample in action. The actual steps are very simple as you can see from this README. What is the example? Software Requirements Structure of the ear file : The final ear looks like this: lib/entities.jar Point to note here are: 2) For sake of clarity, entity beans are packaged in entities.jar and EJB interface classes are packaged in ejb-interfaces.jar. All other modules depend on these two jar files. So sharing them is a challenge. 3) It uses lib directory to share entities.jar and ejb-interfaces.jar with other modules. lib directory is a special directory introduced in Java EE 5. By default its name is lib, but it can be overridden by using application.xml. The intended use is to place library jar files in this directory so that they can be made available to all other modules in the ear file without having to use Class-Path manifest attribute as explained in Bundled Optional Package Support in Java EE 5 platform spec chapter #8. So our entities.jar and ejb-interfaces.jar are automatically available to ejbs.jar, web-app2.war and appclient.jar. This way there is no duplication of classes in the ear. Since entities.jar is placed in lib directory, not only is it available to all other module's class loader, but also the Persistence Unit defined in this jar file is visible to all other modules. 4) ejbs.jar only contains the session bean classes. There is no ejb-jar.xml inside it. Also note that ejbs.jar does not bundle entities.jar, yet it uses the persistence unit which is defined in lib/entities.jar. This is allowed as per the sharing rules of persistence units. 5) web-app2.war contains the servlet classes and html files. 6) In addition to example.client.Main.class appclient.jar contains a META-INF/MANIFEST.MF file.
Step #1: Write entity bean UserCredential.java Points to note about this entity bean are: 2) There is no deployment descriptor needed to specify that it is an entity bean. Instead the class has been annotated as @Entity as shown below: @Entity public class UserCredential implements Serializable. The persistence provider automatically determines whether we are annotating FIELDs or PROPERTIEs. In this case, we have decided to annotate fields. 3) Every entity bean must have an identity. In our case, it is specified using @Id as below. I have chosen to use @Id because we have a single field primary key. Other annotations like @IdClass, @EmbeddedId are typcally used for composite primary key. @Id private String name; 4) Also note that we have not used @GeneratedValue along with @Id. When an id field is not annotated with @GeneratedValue, it means that user is responsible for setting the identity. Provider will not set the id field value. 5) Although it is possible to specify exact table name using @Table and column names using @Column for an entity bean, we can rely on the default mapping that the specification defines and yet expect the application to be portable because this default mapping rule is defined by the spec itself. UserCredential bean gets mapped to a table called USERCREDENTIAL, name & password fields get mapped to NAME and PASSWORD columns respectively. Step #2: Define a persistence unit in persistence.xml A Persistence Unit (PU) is a logical grouping of a set of related entity beans. A PU also contains configuration details about the entity managers that are going to manage these entity beans. Actually the configuration is applied to an EntityManagerFactory which in turn creates homogeneous EntityManager instances. But this is all taken care of by the container to persistence provider interaction. As a user to define a PU, we just need to write a 1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name pu1. 2) We need not specify any other elements/attributes, as the default values are just fine for most applications. e.g. by default the entity manager's transaction type is JTA. 3) There is no need to enumerate all the entity bean class names inside Step #3: Write UserCredentialManagerBean.java Points to note about this EJB 3 style stateless session bean are: 2) There is no deployment descriptor needed to specify that it is a stateless session bean. Instead the class has been annotated as shown below: @Stateless @Remote @Remote annotation is required b'cos the business interface UserCredentialManager is neither annotated as @Local nor as @Remote. So by default our session bean would have exposed a local business interface. Since we want the EJB to be accessible from an application client, having only local interface would not work. So we are using @Remote annotation. The other option would have been to have both local and remote interface, but let's postpone that discussion to some other time. 3) It talks to database using EntityManager API. It declares dependency on an EntityManager using @PersistenceContext annotation: @PersistenceContext private EntityManager em; Since there is only one Persistence Unit(PU) defined in the scope of this ejb, there is no need to specify the unitName in @PersistenceContext. Please also note that an injected variable in a servlet or ejb must not be declared static or final. In our example, em follows this rule as well. 4) The business method "createUser" creates a new object in the database by one line code: em.persist(uc); The business method "authenticate" uses the following code: UserCredential uc = em.find(UserCredential.class, name); to locates a matching UserCredential object in the database. The business method "removeUser" first locates the named user credential and then calls em.remove(uc); to remove it from the database. Unlike em.find(), em.remove() and em.persist() require an active transaction context. But as you can see none of the EJB methods starts a transaction. That is because by default the transaction management type is CONTAINER and the transaction attribute of business method is REQUIRED. So ejb container takes care of transaction management! This is unlike web container as discussed here. There is no need to write an ejb-jar.xml because a Java EE 5 compatible container can identify ejbs.jar as an EJB module because it contains a class that is annotated as Stateless. Step #4: Write LoginServlet.java Points to note about this servlet are: @EJB private UserCredentialManager ucm; Since there is only one bean that implements this business interface, there is no need to specify any of the attributes of @EJB. 2) When user tries to login using a user name and password, it calls the EJB method to authenticate as shown below: Step #5: Write RegistrationServlet.java Note it also uses an injected EJB. It also calls the createUser EJB method to create a new user. Both the servlets do not do any transaction management, because that is handled by the EJB layer. They also do not explicitly depend on the Java Persistence API. Step #6: Write web.xml We are having to write an web.xml only because we have to define a couple of request path mappings to servlets. Step #7: Write a couple of html files Step #8: Write an appclient Main.java Points to note about this appclient are that: 1) It declares dependency on the EJB using @EJB as shown below: @EJB private static UserCredentialManager ucm; Also note that, the field ucm is static. That's because unlike EJB or Servlets, injected fields in an application client must be static as Application Client Container (ACC) does not instantiate the class, instead it calls the static main(). Since in this ear file, there is only one session bean that implements UserCredentialManager interface, there is no need to specify any other attributes of the EJB. 2) It must be a public class because it will be used by ACC which does not belong to the package of this class. 3) We also need to write a manifest.mf file which must contain the name of the class containing the main() so that ACC knows which is the main class to look for injected fields and main(). Thsi file gets bundled in appclient.jar as META-INF/MANIFEST.MF file. There is no need to write application-client.xml because it is optional. Java EE 5 compatible platform can discover appclient.jar's module type because it contains META-INF/MANIFEST.MF with a Main-Class attribute. Step #9: Build using build.xml This is a very simple build.xml just to demonstrate the compilation and packaging process. As you can see, to compile the sources, only library needed is javaee.jar which contains the Java EE 5 platform APIs. The deploy target in build.xml uses a feature called Java2DB which can automatically create the tables during deployment. This is specific to Sun's app server, but such features are supported in many other commercial applications servers as well. Hope you found this example useful. More blogs about glassfish glassfish persistence persistence An annotation processor to update your persistence.xml during javacPosted by ss141213 on December 13, 2005 at 02:44 PM | Permalink | Comments (1)When Java Persistence API is used in a managed environment (like Java EE container), there is often a deployment step and a notion of deployable module (an ear/war/jar) that represents the boundary of an application. During deployment container/persistence provider can discover managed persistence classes by introspecting .class files bundled in the application. But when Java Persistence API is used in Java SE environment, there is no such predefined deployment step, nor is there any deployable module. So a persistence provider does not know what are all the classes to introspect. Hence the spec requires users to specify the list of managed persistence classes in persistence.xml. A managed persistence class is a class that is either an Entity or Embeddable or EmbeddableSuperclass. In this article, I shall show how to write an Annotation Processor that can be used along with J2SE's Annotation Processing Tool to automatically generate the list of managed persistence classes and update persistence.xml during compilation of entity source code. In the process I will also show how to use JAXB to read and write XML. I suggest you read this if you are not familiar with apt. The complete source code along with a build script is available here. There is also a README that tells you how to build and use the tool. Overview of the source code: 1. AnnotationProcessorFactory: ListPersistenceClassApf.java This is the entry point. It implements AnnotationProcessorFactory interface. 2. AnnotationProcessor: ListPersistenceClassAp.java 3. service provider configuration file: META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory apt is a generic tool that comes with Sun's JDK. It does not know about our custom annotation processor factory. So it has to be told about our annotation processor factory. It can be done in a couple of ways: passing -factory option while invoking apt or by using service provider configuration file. I am using the later approach. 4. Marshalling and unmarshalling of persistence.xml XMLReaderWriter.java As you can see from this source code, I am using JAXB 2.0 RI to read and write persistence.xml. The reason I use JAXB is because it generates the code that is responsible for reading and writing XML from a given schema. See the gen-src target in build.xml to see how we generate code using JAXB. Also take a look at the binding.xjb How to build? The reason I use glassfish is because it implements Java EE 5 spec, which means both Java Persistence API 1.0 as well as JAXB 2.0. How to use? Why do I not have to use .par file to bundle my EJB 3.0 entity beans?Posted by ss141213 on December 06, 2005 at 11:38 PM | Permalink | Comments (7)Public Review version of the Java Persistence API (JPA) spec suggested a new extension par be used to bundle EJB 3 persistence entity beans. It also suggested a new module type called persistence to be used in application.xml, if user uses an application.xml in their ear file containing persistence entity beans. (Note application.xml is optional starting with Java EE 5.) Lot of developers still believe that .par is needed. Looking at the comments in theserverside.com to an earlier posted tutorial showing how to use JPA in web application it is very clear that user community do not want a proliferation of extensions used in Java EE platform. Here is a good news: Here is a simple convention (rule you may say) followed in Java EE platform from early days: As you can see .ear, .war and .rar do not fall into this category, as they do not package classes directly inside them which are used by a standard class loader. Note that although .war sometimes directly contains classes that are used by an applet, but the applet container is not given the .war file, instead it downloads the classes from the web server. I must say having this convention prevented introduction of .par file and it is a relief. This kind of convention is also getting into Java SE, because I have heard in Java SE 6 (mustang) there is going to be a facility to specify a directory in the CLASSPATH environment variable and VM will look for all *.jar files in that directory and add it to CLASSPATH automatically. So if you want to write portable applications, stick to these principles. Sun's next version of application server which is being develped in open sorce project named glassfish does not require any such extensions like .ejb3 or .par. As a result of this not requiring .par files, the most notable simplification is:
EntityManager.persist() throws TransactionRequiredException in a servlet?Posted by ss141213 on December 05, 2005 at 09:37 AM | Permalink | Comments (3)In my last blog I discussed about using Java Persistence API in a web application. In this article I shall talk about a very common mistake that a web-app developer commits and how to fix it. Java Persistence API is part of Java EE 5 platform which is being reference implemented in open source project called glassfish. Code that does not work: public class RegistrationServlet extends HttpServlet {
Exception Details: Why this exception occurs? What is the fix? public class RegistrationServlet extends HttpServlet {
Comparison with equivalent code in a Session Bean @Stateless Let's analyse the differences between ejb and servlet code: Introduction to using Java Persistence API in a web application in Java EE environmentPosted by ss141213 on December 04, 2005 at 03:29 PM | Permalink | Comments (27)The Java Persistence API is the standard API for the management of persistence and object/relational mapping in Java EE 5 platform. Every Java EE 5 compatible application server will support this API. In this entry I will show how to use this API from a web application in Java EE environment. What is the example? Requirements Detailed Steps Step #1: Write entity bean UserCredential.java Points to note about this entity bean are: 2) There is no deployment descriptor needed to specify that it is an entity bean. Instead the class has been annotated as @Entity as shown below: @Entity The persistence provider automatically determines whether we are annotating FIELDs or PROPERTIEs. In this case, we have decided to annotate fields. 3) Every entity bean must have an identity. In our case, it is specified using @Id as below: @Id private String name; I have chosen to use @Id because we have a single field primary key. Other annotations like @IdClass, @EmbeddedId are typcally used for composite primary key. 4) Also note that we have not used @GeneratedValue along with @Id. When an id field is not annotated with @GeneratedValue, it means that user is responsible for setting the identity. Provider will not set the id field. 5) Although it is possible to specify exact table name and column names for the entity bean, we can rely on the default mapping that the specification defines. Because of the default mapping rules, UserCredential bean gets mapped to a table called USERCREDENTIAL, name & password fiels get mapped to NAME and PASSWORD columns respectively. Step #2: Define a persistence unit A Persistence Unit (PU) is a logical grouping of a set of related entity beans. A PU also contains configuration details about the entity managers that are going to manage these entity beans. Actually the ocnfiguration is applied to an EntityManagerFactory which in turn creates homogenious entity manager instances. To define a PU we need to write a 1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name em1. 2) We need not specify any other elements/attributes, as the default values are just fine for most applications. e.g. by default the entity manager's transaction type is JTA. 3) There is no need to enumerate all the entity bean class names inside Step #3: Write LoginServlet.java Points to note about this servlet are: @PersistenceUnit private EntityManagerFactory emf; Since there is only one Persistence Unit(PU) defined in the scope of the web-app, there is no need to specify the unitName in @PersistenceUnit. Please also note that an injected variable in a servlet or ejb must not be declared static or final. In our example, emf follows this rule as well. 2) Also note that the servlet does not have an instance field of type EntityManager. This is because EntityManager is not thread safe. Since this servlet is not denoted as a SingleThreadModel servlet, one instance of servlet gets shared by mutiple clients and service method of servlet can be called by multiple threads concurrently. So we can't directly inject an EntityManager. Instead we inject an EntityManagerFactory which is thread safe. 3) In the service(), we create an EntityManager using the following code: EntityManager em = emf.createEntityManager(); We also close the EntityManager in the finally block. 4) When user tries to login using a user name and password, it uses to find a matching UserCredential entity in the database. 5) Since EntityManager.find does not require a transaction to be started, the servlet does not have to begin a transaction before calling em.find(). Step #4: Write RegistrationServlet.java Note: 2) It uses EntityManager.persist() to create a new entity in the in the database . 3) Since EntityManager.persist() needs to be called in the context of a transaction, this servlet begins a transaction by calling utx.begin() and commits the tx before returning. 4) Also note that it uses an injected UserTransaction object as follows: @Resource private UserTransaction utx; Unlike EntityManager, UserTransaction is thread safe, so it is OK to inject it into a servlet. 5) Also see how we ensure that when we close the EntityManager there is no active transaction context, otherwise EntityManager.close() will throw an exception. Step #5: Write web.xml We are having to write an web.xml only because we have to define a couple of request path mappings to servlets. Step #6: Write a couple of html files Step #7: Build using build.xml This is a very simple build.xml just to demonstrate the compilation and packaging process. As you can see, to compile only library needed is javaee.jar which contains the Java EE 5 platform APIs. a) build-entities target which compiles only entity beans, copies persistence.xml to output directory and make a jar file called entities.jar. See entities.jar contains persistence.xml in META-INF dir. This jar file is used during compilation of servlets. More over this is also bundled inside the war file's WEB-INF/lib directory. b) build-web-app1 target which compiles the servlets, copies web.xml and html files to output directories amd makes a war file called web-app1.war. A few points worth noting here are: Step #8 | ||