<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1468532151642511496</id><updated>2011-12-30T19:08:27.770-08:00</updated><category term='weld'/><category term='scopes'/><category term='transactions'/><category term='jsf'/><category term='java'/><category term='conversations'/><category term='ejb'/><category term='java-ee'/><category term='seam'/><category term='authentication'/><category term='security'/><category term='jsr-299'/><category term='jboss'/><category term='cdi'/><category term='security-domain'/><category term='JAAS'/><category term='authorization'/><title type='text'>That Java Thing</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1468532151642511496.post-5452718217234004484</id><published>2010-05-18T14:23:00.000-07:00</published><updated>2010-11-27T08:51:26.494-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java-ee'/><category scheme='http://www.blogger.com/atom/ns#' term='scopes'/><category scheme='http://www.blogger.com/atom/ns#' term='weld'/><category scheme='http://www.blogger.com/atom/ns#' term='seam'/><category scheme='http://www.blogger.com/atom/ns#' term='conversations'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr-299'/><category scheme='http://www.blogger.com/atom/ns#' term='cdi'/><title type='text'>Conversation scope: CDI (JSR-299) vs Seam 2</title><content type='html'>&lt;p&gt;CDI (JSR-299) is the new Java standard for contextual type-safe dependency injection and as such it is an integral part of Java EE 6 platform. Still, it will also work in any other environment, be it a servlet container or simple Java SE. It was insipered by Seam 2 (and what is therein known as 'bijection') and Guice.&lt;/p&gt;&lt;h3&gt;The Naming Game&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Initially, CDI was known as WebBeans but the name had been changed before the spec was finalized. The reference implementation is called Weld but was also at some point called WebBeans. Yet again, that name is now obsolete as should not be used. Thus, WebBeans now refers to... well... nothing, so you're free to forget all about it. You will still see the old name popping up around the Web occasionally but it should fade into oblivion soon enough. More info on this story can be found at the very beginning of the reference documentation.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Conversations&lt;/h3&gt;&lt;br /&gt;The existance of a built-in conversation scope in CDI will immediately lure most of the Seam 2 developers into a wrong assumption of familiarity. Wrong because although they serve the same purpose conversations in CDI and Seam 2 do not always behave identically.&lt;br /&gt;While all Seam's conversations, both transient and long-running, invariantly survive redirects (unless specifically instructed not to through &lt;span class="snippet"&gt;endBeforeRedirect=true&lt;/span&gt;), conversations in CDI will survive only if they are promoted to long-running (through &lt;span class="snippet"&gt;conversation.begin()&lt;/span&gt; ) during the original request. A transient conversation will be destroyed at the end of the original request and a new one will be spawned for each redirect. In other words, without a long-running conversation, conversation scoped components in Seam 2 will behave (by default) as if they were in what you might know as flash scope from other frameworks and languages (this scope will also exist in Seam 3 with the related annotation &lt;span class="snippet"&gt;@FlashScoped&lt;/span&gt;). Under the same conditions, &lt;span class="snippet"&gt;@ConversationScoped&lt;/span&gt; beans in CDI will behave as if they were &lt;span class="snippet"&gt;@RequestScoped&lt;/span&gt;. In case a long-running conversation is present, the behavior will be the same in both Seam 2 and CDI.&lt;br /&gt;&lt;p&gt;Reference documentation for some reason never states this explicitly so it can be very misleading for Seam 2 developers. Luckily though, there's &lt;a href="http://seamframework.org/Seam3/Seam2ToSeam3MigrationNotes"&gt;a table&lt;/a&gt; on the official site mapping Seam 2 scopes to their CDI equivalents where possible and gives brief description of the differences.&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;br /&gt;To further clarify this (probably needlessly), let's illustrate with a simple example implemented both in Seam 2 and CDI.&lt;br /&gt;In order to keep everything at a bare minimum, we'll just create a single component (or bean if you prefer), named &lt;span class="snippet"&gt;MessageBean&lt;/span&gt;, and a single Facelets view that accepts the new input and attempts to display the previous one after a redirect.&lt;br /&gt;Note: Import and package statements are omitted from the following code listings.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Seam 2 version&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="snippet"&gt;MessageBean&lt;/span&gt; class:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Name("msg")&lt;br /&gt;@Scope(ScopeType.CONVERSATION)&lt;br /&gt;public class MessageBean implements Serializable {&lt;br /&gt;&lt;br /&gt;  private String message;&lt;br /&gt;&lt;br /&gt;  public String getMessage() {&lt;br /&gt;          return message;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setMessage(String message) {&lt;br /&gt;    this.message = message;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String redir() {&lt;br /&gt;    return "redir";&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;CDI version&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;You'll notice a striking resemblance to the Seam 2 version.&lt;br /&gt;&lt;br /&gt;&lt;span class="snippet"&gt;MesageBean&lt;/span&gt; class:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Named("msg")&lt;br /&gt;@ConversationScoped&lt;br /&gt;public class MessageBean implements Serializable {&lt;br /&gt;&lt;br /&gt;  // @Inject Conversation conversation;&lt;br /&gt;  private String message;&lt;br /&gt;&lt;br /&gt;  public String getMessage() {&lt;br /&gt;    return message;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setMessage(String message) {&lt;br /&gt;    this.message = message;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String redir() {&lt;br /&gt;    //if (conversation.isTransient())&lt;br /&gt;    // conversation.begin();&lt;br /&gt;    return "redir";&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Facelets view&lt;/strong&gt; (the same in both cases):&lt;br /&gt;&lt;br /&gt;Note: Again, extra headers are omitted.&lt;br /&gt;&lt;br /&gt;&lt;span class="snippet"&gt;input.xhtml&lt;/span&gt;:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt;xmlns:ui="http://java.sun.com/jsf/facelets"&lt;br /&gt;xmlns:h="http://java.sun.com/jsf/html"&lt;br /&gt;xmlns:f="http://java.sun.com/jsf/core"&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;Previous input: #{msg.message}&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;h:form&amp;gt;&lt;br /&gt;&amp;lt;h:inputText id="messageText" value="#{msg.message}" required="true"/&amp;gt;&lt;br /&gt;&amp;lt;h:commandButton id="redirectButton" value="Redirect" action="#{msg.redir}"/&amp;gt;&lt;br /&gt;&amp;lt;/h:form&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;strong&gt;Configuration&lt;/strong&gt; (the same in both cases):&lt;br /&gt;&lt;br /&gt;&lt;span class="snippet"&gt;faces-config.xml&lt;/span&gt;:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;navigation-rule&amp;gt;&lt;br /&gt;&amp;lt;navigation-case&amp;gt;&lt;br /&gt;&amp;lt;from-outcome&amp;gt;redir&amp;lt;/from-outcome&amp;gt;&lt;br /&gt;&amp;lt;to-view-id&amp;gt;/input.xhtml&amp;lt;/to-view-id&amp;gt;&lt;br /&gt;&amp;lt;redirect /&amp;gt;&lt;br /&gt;&amp;lt;/navigation-case&amp;gt;&lt;br /&gt;&amp;lt;/navigation-rule&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you were to execute both these examples, you'd soon realize the difference between the frameworks. While Seam 2 version keeps your input across the redirect and displays it on the next rendering, even without promoting the conversation, CDI will destroy the context on redirect leaving you with no message to  display. Note that if the commented lines in the CDI version of &lt;span class="snippet"&gt;MessageBean&lt;/span&gt; were to be uncommented, thus promoting the conversation to a long-running one, the message would survive, together with the whole conversation context (which would afterwards be reused in the next cycle in this case). Normally, you'd also want a way to end the conversation at some point through &lt;span class="snippet"&gt;conversation.end()&lt;/span&gt; instead of waiting for the timeout (which is ultimately decided by the server).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Download&lt;/h3&gt;&lt;br /&gt;Below you can find both implementations as war files ready for deployment. The examples are meant to be deployed to JBoss AS so some tweaks (like adding Weld or any other CDI implementation jar to the classpath) might be needed in order to get it running on Tomcat or other servers/containers.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.drivehq.com/file/df.aspx/publish/veggen/PublicFolder/conversationsCDI.war"&gt;conversationCDI.war&lt;/a&gt; (tested on JBoss AS 6)&lt;br /&gt;&lt;a href="http://www.drivehq.com/file/df.aspx/publish/veggen/PublicFolder/conversationsSeam.war"&gt;conversationsSeam.war&lt;/a&gt; (tested on JBoss AS 5, does not work on JBoss AS 6 for some reason)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;References&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://www.seamframework.com/Weld"&gt;Weld main site&lt;/a&gt;&lt;br /&gt;&lt;a href="http://docs.jboss.org/seam/latest/en-US/html/"&gt;Seam 2 tutorial&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1468532151642511496-5452718217234004484?l=thatjavathing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/5452718217234004484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thatjavathing.blogspot.com/2010/05/conversation-scope-cdi-jsr-299-vs-seam.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/5452718217234004484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/5452718217234004484'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/2010/05/conversation-scope-cdi-jsr-299-vs-seam.html' title='Conversation scope: CDI (JSR-299) vs Seam 2'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1468532151642511496.post-5219667880073992694</id><published>2010-03-14T16:00:00.001-07:00</published><updated>2010-04-08T05:02:17.001-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='transactions'/><category scheme='http://www.blogger.com/atom/ns#' term='java-ee'/><category scheme='http://www.blogger.com/atom/ns#' term='seam'/><title type='text'>Global transactions in Seam</title><content type='html'>Transactions grew to be a necessity in most today's applications, and managing them grew to be a demanding task. If the application is complex enough it can evolve into a nightmare in its own right. Thus, offloading this task to a framework whenever possible is a very desirable approach.&lt;br /&gt;Being a powerful feature-packed framework that it is, Seam offers exceptional support for transactional behavior that in many instances surpasses all others. One feature not seen in other frameworks are global transactions.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The confusion&lt;/h3&gt;&lt;br /&gt;This topic is regarded as somewhat arcane, despite being essentially simple. The reason for this is twofold. Firstly, the documentation regarding global transactions is relatively poor. Secondly, and more importantly, the exiting documentation does not call this feature &lt;em&gt;global transactions&lt;/em&gt;, and this is the term used most widely over the internet (it was originally coined by Dan Allen is his book &lt;em&gt;Seam in Action&lt;/em&gt;, often regarded as the "default" book for Seam).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Clearing it up&lt;/h3&gt;&lt;br /&gt;In essence, global transactions refer to the two or three transactions that wrap each request in Seam. The first one wraps JSF phases beginning with Restore View (for JTA transactions) or Invoke Application (for resource-local transactions), and ending just before Render Response. The second wraps all page actions (if they are used), and the third wraps the Render Response phase. During this final transaction, the context flushing is disabled, effectively rendering the whole transaction read-only.&lt;br /&gt;In this fashion, Seam accomplishes a couple of things:&lt;ul&gt;&lt;li&gt;an error in page preparation or rendering will never role back a successfully executed business logic,&lt;/li&gt; &lt;br /&gt;&lt;li&gt;view rendering is executed atomically, which not only avoids opening and closing a transaction on every lazy initialization, but also guarantees isolation and guards against accidental changes of the state during this phase,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;page actions are executed atomically (with benefits similar to those mentioned above sans disabled context flushing).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This way, Seam effectively does away with a good portion of the most common problems of transaction management.&lt;br /&gt;To effectively use global transactions, one should keep in mind that Seam turns them on by default. To turn them off, you'll need to disable Seam's transaction management all together. This is done by adding&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;core:init transaction-management-enabled=&amp;#34;false&amp;#34;/&amp;gt;&lt;/pre&gt;&lt;br /&gt;to the component descriptor file.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Notes&lt;/h3&gt;&lt;br /&gt;It should also be noted that, despite what can be read in some sources, &lt;span class="snippet"&gt;@Transactional&lt;/span&gt; annotation is not unusable in conjunction with global transactions. The point here is that since there is an overarching transaction, no new transactions will be spawned to encompass annotated business methods, effectively ignoring &lt;span class="snippet"&gt;@Transactional&lt;/span&gt;. Of course, an overarching transaction will only be present during a JSF postback. On non-JSF calls, &lt;span class="snippet"&gt;@Transactional&lt;/span&gt; will still do it's job normally. This misunderstanding was caused by a somewhat ambiguous statement in &lt;em&gt;Seam in Action&lt;/em&gt;.&lt;br /&gt;To recap, &lt;em&gt;global translations&lt;/em&gt; is just another name for (as Dan Allen would put it) &lt;em&gt;"automatic transaction wrapped around the request"&lt;/em&gt;. A useful feature which one should always keep in mind when developing applications in Seam.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1468532151642511496-5219667880073992694?l=thatjavathing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/5219667880073992694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thatjavathing.blogspot.com/2010/03/global-transactions-in-seam_14.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/5219667880073992694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/5219667880073992694'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/2010/03/global-transactions-in-seam_14.html' title='Global transactions in Seam'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1468532151642511496.post-3875068469601558694</id><published>2009-05-30T06:18:00.000-07:00</published><updated>2009-06-15T06:34:57.129-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='authorization'/><category scheme='http://www.blogger.com/atom/ns#' term='java-ee'/><category scheme='http://www.blogger.com/atom/ns#' term='JAAS'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='security-domain'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Authentication and authorization with JBoss security domains</title><content type='html'>Authentication and authorization comprise the fundamentals of security, and as such, they are important aspects of almost any application. Having in mind that security is such a frequent issue, it comes as no surprise that many people have devised many different ways of carrying it out, and so we now have literally countless options to choose from. If you are going to deploy your application to JBoss AS, you can get the basic authentication and authorization set up in virtually no time. To carry out these tasks, JBoss uses the notion of a security domain overlaying the standard JAAS (Java Authentication and Authorization Service).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Configuring the data source (&lt;span class="snippet"&gt;*-ds.xml&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;In order to set up a security domain for your app to use, you first need to set up a data source against which you will check the user's credentials. More often than not, your source of data will be a relational database. JBoss conveniently provides templates for many populars databases, so setting up a data source should be a breeze. These templates can be found under&lt;br /&gt;&lt;strong&gt;&amp;lt;JBoss home&amp;gt;/docs/examples/jca&lt;sup&gt;1&lt;/sup&gt;&lt;/strong&gt;. Notice that all the filenames in this directory end with "-ds". This is the convention for naming the data source configuration files.&lt;br /&gt;&lt;br /&gt;Let's assume we want to use MySQL. All we need to do, is make a copy of mysql-ds.xml, edit it to reflect our situation, and put it into the deployment directory. Editing this file is pretty straight forward, you decide on a JNDI name you want your data source bound to (I'll use &lt;span class="snippet"&gt;MySqlDS&lt;/span&gt;), input your connection URL, username and password. There's really no need to change the driver class.&lt;br /&gt;&lt;br /&gt;When this is done, you place this file under &lt;strong&gt;&amp;lt;JBoss home&amp;gt;/server/&amp;lt;profile name&amp;gt;/deploy&lt;sup&gt;2&lt;/sup&gt;&lt;/strong&gt;. That's it for this step.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Configuring a security domain (&lt;span class="snippet"&gt;login-config.xml&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Next, you need to edit JBoss' &lt;span class="snippet"&gt;login-config.xml&lt;/span&gt; file (found under&amp;lt;JBoss home&amp;gt;/server/&amp;lt;profile name&amp;gt;/conf). There are other ways to set up the security domain, but is by far the easiest. All you need to do here is nest a snippet similar to the following inside the &lt;span class="snippet"&gt;policy&lt;/span&gt; element.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;!-- My custom security domain --&amp;gt;&lt;br /&gt;  &amp;lt;application-policy name=&amp;#34;custom-domain&amp;#34;&amp;gt;&lt;br /&gt;   &amp;lt;authentication&amp;gt;&lt;br /&gt;      &amp;lt;login-module code=&amp;#34;org.jboss.security.auth.spi.DatabaseServerLoginModule&amp;#34;&lt;br /&gt;        flag = &amp;#34;required&amp;#34;&amp;gt;&lt;br /&gt;         &amp;lt;module-option name=&amp;#34;dsJndiName&amp;#34;&amp;gt;java:/MySqlDS&amp;lt;/module-option&amp;gt;&lt;br /&gt;         &amp;lt;module-option name=&amp;#34;principalsQuery&amp;#34;&amp;gt;SELECT password FROM USERS WHERE username=?&amp;lt;/module-option&amp;gt;&lt;br /&gt;         &amp;lt;module-option name=&amp;#34;rolesQuery&amp;#34;&amp;gt;SELECT role, 'Roles' FROM ROLES WHERE username=?&amp;lt;/module-option&amp;gt;&lt;br /&gt;      &amp;lt;/login-module&amp;gt;&lt;br /&gt;   &amp;lt;/authentication&amp;gt;&lt;br /&gt;  &amp;lt;/application-policy&amp;gt;&lt;/pre&gt;&lt;br /&gt;Pay attention that &lt;span class="snippet"&gt;dsJndiName&lt;/span&gt; attribute value must be identical to the &lt;span class="snippet"&gt;jndi-name&lt;/span&gt; you chose in your &lt;span class="snippet"&gt;mysql-ds.xml&lt;/span&gt;, preceded by &lt;span class="snippet"&gt;java:/&lt;/span&gt;.&lt;br /&gt;&lt;span class="snippet"&gt;principalsQuery&lt;/span&gt; is the SQL query used to retrieve the user's password which, of course, has to match the one entered, and &lt;span class="snippet"&gt;rolesQuery&lt;/span&gt; is the SQL query used to retrieve the roles associated with the user (leave the &lt;span class="snippet"&gt;'Roles'&lt;/span&gt; part as it is, it's not clear from the JBoss' documentation what purpose it has).&lt;br /&gt;&lt;br /&gt;Our security domain is now ready. The next thing to do would be to instruct our application to use it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Declaring page-level security (&lt;span class="snippet"&gt;web.xml&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Presume we have a &lt;span class="snippet"&gt;web.xml&lt;/span&gt; with the following security constraints configured:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;security-constraint&amp;gt;&lt;br /&gt;   &amp;lt;web-resource-collection&amp;gt;                     &lt;br /&gt;      &amp;lt;web-resource-name&amp;gt;Secure Resource&amp;lt;/web-resource-name&amp;gt;&lt;br /&gt;      &amp;lt;url-pattern&amp;gt;/secure/*&amp;lt;/url-pattern&amp;gt;           &lt;br /&gt;   &amp;lt;/web-resource-collection&amp;gt;&lt;br /&gt;   &amp;lt;auth-constraint&amp;gt;                               &lt;br /&gt;      &amp;lt;role-name&amp;gt;registereduser&amp;lt;/role-name&amp;gt;  &lt;br /&gt;   &amp;lt;/auth-constraint&amp;gt;                              &lt;br /&gt;  &amp;lt;/security-constraint&amp;gt;                       &lt;br /&gt;&amp;lt;login-config&amp;gt;&lt;br /&gt;   &amp;lt;auth-method&amp;gt;FORM&amp;lt;/auth-method&amp;gt;&lt;br /&gt;   &amp;lt;form-login-config&amp;gt;&lt;br /&gt;      &amp;lt;form-login-page&amp;gt;/login.html&amp;lt;/form-login-page&amp;gt;&lt;br /&gt;      &amp;lt;form-error-page&amp;gt;/error.html&amp;lt;/form-error-page&amp;gt;&lt;br /&gt;   &amp;lt;/form-login-config&amp;gt;&lt;br /&gt;&amp;lt;/login-config&amp;gt;&lt;br /&gt;&amp;lt;security-role&amp;gt;                                  &lt;br /&gt;   &amp;lt;role-name&amp;gt;registereduser&amp;lt;/role-name&amp;gt;&lt;br /&gt;&amp;lt;/security-role&amp;gt;&lt;br /&gt;  &amp;lt;resource-ref&amp;gt;&lt;br /&gt;    &amp;lt;res-ref-name&amp;gt;jdbc/mysql&amp;lt;/res-ref-name&amp;gt;&lt;br /&gt;    &amp;lt;res-type&amp;gt;javax.sql.DataSource&amp;lt;/res-type&amp;gt;&lt;br /&gt;    &amp;lt;res-auth&amp;gt;Container&amp;lt;/res-auth&amp;gt;&lt;br /&gt;  &amp;lt;/resource-ref&amp;gt;&lt;/pre&gt;&lt;br /&gt;This tells our app server that only the users with the &lt;span class="snippet"&gt;registereduser&lt;/span&gt; role can access the resources under &lt;span class="snippet"&gt;/secure/&lt;/span&gt; (this is the job of the &lt;span class="snippet"&gt;url-pattern&lt;/span&gt; element). It also tells we are going to use a form to perform authentication (notice the &lt;span class="snippet"&gt;auth-method&lt;/span&gt; element), and that this form is found on the page named &lt;span class="snippet"&gt;login.html&lt;/span&gt; (the &lt;span class="snippet"&gt;form-login-page&lt;/span&gt; element). The request gets redirected to the page specified under &lt;span class="snippet"&gt;form-error-page&lt;/span&gt; in case the login failed. You can also use &lt;span class="snippet"&gt;BASIC&lt;/span&gt; authentication method (just place &lt;span class="snippet"&gt;BASIC&lt;/span&gt; instead of &lt;span class="snippet"&gt;FORM&lt;/span&gt; inside &lt;span class="snippet"&gt;auth-method&lt;/span&gt; element) . This will cause the browser to display a simple pop-up dialog that asks for username and password when a secured resource is requested. You don't need &lt;span class="snippet"&gt;form-login-config&lt;/span&gt; for this approach.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creating a login form (&lt;span class="snippet"&gt;j_security_check&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;The login page is obviously required to contain a login form. This form must specify &lt;span class="snippet"&gt;j_security_check&lt;/span&gt; as it's action, and it also must have a username input field named &lt;span class="snippet"&gt;j_username&lt;/span&gt; and a password input field named &lt;span class="snippet"&gt;j_password&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;This is how it might look like in it's simplest form:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;form name=&amp;#34;loginForm&amp;#34; method=&amp;#34;post&amp;#34; action=&amp;#34;j_security_check&amp;#34;&amp;gt;&lt;br /&gt;&amp;lt;table&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;        &amp;lt;td&amp;gt;User Name:&amp;lt;/td&amp;gt;&lt;br /&gt;        &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;text&amp;#34; name=&amp;#34;j_username&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;        &amp;lt;td&amp;gt;Password:&amp;lt;/td&amp;gt;&lt;br /&gt;        &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;password&amp;#34; name=&amp;#34;j_password&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;    &amp;lt;tr colspan=&amp;#34;2&amp;#34;&amp;gt;&lt;br /&gt;        &amp;lt;td&amp;gt;&amp;lt;input type=&amp;#34;submit&amp;#34; value=&amp;#34;login&amp;#34;&amp;gt;&amp;lt;/td&amp;gt;            &lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Binding the application to a security domain (&lt;span class="snippet"&gt;jboss-web.xml&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;So, &lt;span class="snippet"&gt;web.xml&lt;/span&gt; dictates the security constraints, but there is no mention of how these constraints will be carried out. This is the job of the &lt;span class="snippet"&gt;jboss-web.xml&lt;/span&gt; config file (which is, of course, JBoss specific). It is in this file where we specify what security domain we want to use for authentication. Here's how it should look like in this case:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;br /&gt;&amp;lt;jboss-web&amp;gt;&lt;br /&gt;    &amp;lt;security-domain&amp;gt;java:/jaas/custom-domain&amp;lt;/security-domain&amp;gt;&lt;br /&gt;    &amp;lt;resource-ref&amp;gt;&lt;br /&gt;        &amp;lt;res-ref-name&amp;gt;jdbc/mysql&amp;lt;/res-ref-name&amp;gt;&lt;br /&gt;        &amp;lt;res-type&amp;gt;javax.sql.DataSource&amp;lt;/res-type&amp;gt;&lt;br /&gt;        &amp;lt;jndi-name&amp;gt;java:/MySqlDS&amp;lt;/jndi-name&amp;gt;&lt;br /&gt;    &amp;lt;/resource-ref&amp;gt;&lt;br /&gt;&amp;lt;/jboss-web&amp;gt;&lt;/pre&gt;&lt;br /&gt;Pay attention to the &lt;span class="snippet"&gt;security-domain&lt;/span&gt; element. It is necessary to prefix the domain name with &lt;span class="snippet"&gt;java:/jaas/&lt;/span&gt;, and the name its self must be exactly the same as the one you typed into the &lt;span class="snippet"&gt;login-config.xml&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;That's it! Now every unauthenticated request to the secure resource (under &lt;span class="snippet"&gt;/secure/&lt;/span&gt;, as specified in &lt;span class="snippet"&gt;web.xml&lt;/span&gt;) will first be redirected to the login page (or, in case of &lt;span class="snippet"&gt;BASIC auth-method&lt;/span&gt;, a login pop-up will displayed). If the user logs in successfully and is authorized i.e. associated with any of the required roles (only &lt;span class="snippet"&gt;registereduser&lt;/span&gt; in our case), the requested resource will be displayed. Otherwise, if the login attempt fails, or the user doesn't have any of the required roles, the error page will be displayed instead. Users stay logged in for the entire duration of the session.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Method-level security (&lt;span class="snippet"&gt;isUserInRole&lt;/span&gt;)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Declarative security in &lt;span class="snippet"&gt;web.xml&lt;/span&gt; is enough if you only need page-level security (based on the URL pattern), but if you need to dynamically check user's role on a method level, you can do so by calling &lt;span class="snippet"&gt;isUserInRole("registereduser")&lt;/span&gt; on a request object (acquired from the &lt;span class="snippet"&gt;ExtrnalContext&lt;/span&gt;). Here's a short example of a method doing this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public Boolean isRegisteredUser() {&lt;br /&gt;HttpServletRequest httpServletRequest =&lt;br /&gt;(HttpServletRequest) FacesContext.getCurrentInstance() //first get the current FacesContext instance&lt;br /&gt;.getExternalContext() //than get the ExternalContext&lt;br /&gt;.getRequest(); //get the underlying request&lt;br /&gt;// return True if this request was issued by a user with a "registereduser" role&lt;br /&gt;return httpServletRequest.isUserInRole("registereduser"); &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;You can get the username in pretty much the same way, just call &lt;span class="snippet"&gt;getRemoteUser()&lt;/span&gt; instead of &lt;span class="snippet"&gt;isUserInRole("...")&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;strong&gt;&amp;lt;JBoss home&amp;gt;&lt;/strong&gt; refers to your JBoss installation directory (the same as &lt;span class="snippet"&gt;JBOSS_HOME&lt;/span&gt; environmental variable).&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; &lt;strong&gt;&amp;lt;profile name&amp;gt;&lt;/strong&gt; refers to your deployment profile name (you will probably be using &lt;span class="snippet"&gt;default&lt;/span&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1468532151642511496-3875068469601558694?l=thatjavathing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/3875068469601558694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thatjavathing.blogspot.com/2009/05/authentication-and-authorization-with_30.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/3875068469601558694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/3875068469601558694'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/2009/05/authentication-and-authorization-with_30.html' title='Authentication and authorization with JBoss security domains'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1468532151642511496.post-6978630423828191221</id><published>2009-04-05T04:21:00.000-07:00</published><updated>2009-04-06T01:27:01.389-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java-ee'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Validators in JSF</title><content type='html'>In JSF, validators are components that provide a mechanism for clean and easy validation of user input and, if necessary, generation of messages that can be displayed back to the client.&lt;br /&gt;&lt;br /&gt;JSF comes with some basic built-in validators, but it allows for new, custom ones, to be added by the developer.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Built-in validators&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;The following validators are available out of the box:&lt;br /&gt;&lt;br /&gt;• &lt;span class="snippet"&gt;f:validateDoubleRange&lt;/span&gt;: Checks whether a numeric input (convertible to &lt;span class="snippet"&gt;double&lt;/span&gt;) is within a specified range.&lt;br /&gt;• &lt;span class="snippet"&gt;f:validateLength&lt;/span&gt;: Checks if the string input length is within a given range.&lt;br /&gt;• &lt;span class="snippet"&gt;f:validateLongRange&lt;/span&gt;: Checks whether a numeric input (convertible to &lt;span class="snippet"&gt;long&lt;/span&gt;) is within a given range.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In order to be used, a validator needs to be nested into an &lt;span class="snippet"&gt;h:input&lt;/span&gt; component that requires it.&lt;br /&gt;To dictate the boundaries of the acceptable range, you need to specify the values for the &lt;span class="snippet"&gt;minimum&lt;/span&gt; and/or &lt;span class="snippet"&gt;maximum&lt;/span&gt; attributes to each of these validators.&lt;br /&gt;&lt;br /&gt;Let's exemplify this. Assume we were creating an application that calculates monthly rates for the chosen loan. The client is expected to input the number of months they require the loan for, but our application does not allows this to be less than 6 or greater than 120 (or 10 years).&lt;br /&gt;&lt;br /&gt;If we had a backing bean called &lt;span class="snippet"&gt;loansManager&lt;/span&gt; and, within it, a &lt;span class="snippet"&gt;HtmlInputText&lt;/span&gt; field, the component we would use would look like this:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;h:inputText id=&amp;#34;account&amp;#34; required=&amp;#34;true&amp;#34;&lt;br /&gt;binding=&amp;#34;#{loansManager.client.accountNumber}&amp;#34;&lt;br /&gt;requiredMessage=&amp;#34;Value is required!&amp;#34;&amp;gt;&lt;br /&gt;&amp;lt;f:validator validatorId=&amp;#34;AccountNumberValidator&amp;#34;/&amp;gt;&lt;br /&gt;&amp;lt;/h:inputText&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Custom validators&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;If you need validation beyond the scope of the afore mentioned built-in components, you will have to write a custom validator to take care of your requirements.&lt;br /&gt;&lt;br /&gt;You have two options here, to create a validator class or to create a validator method in one of your backing beans.&lt;br /&gt;&lt;br /&gt;The first approach means implementing the &lt;span class="snippet"&gt;Validator&lt;/span&gt; interface and it's &lt;span class="snippet"&gt;validate&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;This time assume our application expects the client to input his account number in form ***.*******.**, where each * represents one character (probably should be a digit, but let's keep it simple).&lt;br /&gt;&lt;br /&gt;The implementing class would then look like this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package loans.validators;&lt;br /&gt;&lt;br /&gt;import javax.faces.application.FacesMessage;&lt;br /&gt;import javax.faces.component.UIComponent;&lt;br /&gt;import javax.faces.context.FacesContext;&lt;br /&gt;import javax.faces.validator.Validator;&lt;br /&gt;import javax.faces.validator.ValidatorException;&lt;br /&gt;&lt;br /&gt;public class AccountNumberValidator implements Validator {&lt;br /&gt;&lt;br /&gt; public AccountNumberValidator() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void validate(FacesContext ctxt, UIComponent cmp, Object val) {&lt;br /&gt;  &lt;br /&gt;  String message = null;&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   String[] parts = ((String)val).split("-");&lt;br /&gt;   if (parts.length &lt; 3)&lt;br /&gt;    message = "Wrong account number!";&lt;br /&gt;   else {&lt;br /&gt;    if (parts[0].length() != 3 || parts[1].length() != 7 || parts[2].length() != 2)&lt;br /&gt;     message = "Wrong account number!";&lt;br /&gt;   }&lt;br /&gt;  } catch (Exception e){}&lt;br /&gt;&lt;br /&gt;  if (message != null) {&lt;br /&gt;   FacesMessage msg = new FacesMessage(&lt;br /&gt;     FacesMessage.SEVERITY_ERROR, message, message);&lt;br /&gt;   throw new ValidatorException(msg);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;To register this validator, you would have to add the following snippet to your &lt;span class="snippet"&gt;faces-config.xml&lt;/span&gt; file:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;validator&amp;gt;&lt;br /&gt;&amp;lt;validator-id&amp;gt;AccountNumberValidator&amp;lt;/validator-id&amp;gt;&lt;br /&gt;&amp;lt;validator-class&amp;gt;loans.validators.AccountNumberValidator&amp;lt;/validator-class&amp;gt;&lt;br /&gt;&amp;lt;/validator&amp;gt;&lt;/pre&gt;&lt;br /&gt;Now, you can add your validator to any &lt;span class="snippet"&gt;h:input&lt;/span&gt; component that requires it.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;h:inputText id=&amp;#34;account&amp;#34; required=&amp;#34;true&amp;#34;&lt;br /&gt;binding=&amp;#34;#{loansManager.client.accountNumber}&amp;#34;&lt;br /&gt;requiredMessage=&amp;#34;Value is required!&amp;#34;&amp;gt;&lt;br /&gt;&amp;lt;f:validator validatorId=&amp;#34;AccountNumberValidator&amp;#34;/&amp;gt;&lt;br /&gt;&amp;lt;/h:inputText&amp;gt;&lt;/pre&gt;&lt;br /&gt;The second option, mentioned earlier, is writing a validator method instead. For this, we would make a &lt;span class="snippet"&gt;validateAccountNumber&lt;/span&gt; method in our &lt;span class="snippet"&gt;loansManager&lt;/span&gt; backing bean. The method should look like this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void validateAccountNumber(FacesContext ctxt, UIComponent cmp, Object val) {&lt;br /&gt;  &lt;br /&gt;  String message = null;&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   String[] parts = ((String)val).split("-");&lt;br /&gt;   if (parts.length &lt; 3)&lt;br /&gt;    message = "Wrong account number!";&lt;br /&gt;   else {&lt;br /&gt;    if (parts[0].length() != 3 || parts[1].length() != 7 || parts[2].length() != 2)&lt;br /&gt;     message = "Wrong account number!";&lt;br /&gt;   }&lt;br /&gt;  } catch (Exception e){}&lt;br /&gt;&lt;br /&gt;  if (message != null) {&lt;br /&gt;   FacesMessage msg = new FacesMessage(&lt;br /&gt;     FacesMessage.SEVERITY_ERROR, message, message);&lt;br /&gt;   ctxt.addMessage(cmp.getClientId(ctxt), mess);&lt;br /&gt;  }&lt;br /&gt; }&lt;/pre&gt;&lt;br /&gt;Note that this time, instead of throwing a validator exception, we're manually adding a message the &lt;span class="snippet"&gt;FacesContext&lt;/span&gt;'s queue. In the previous example this was done automatically.&lt;br /&gt;&lt;br /&gt;To use this new validator, you would add it to your &lt;span class="snippet"&gt;h:input&lt;/span&gt; component like this:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;h:inputText id=&amp;#34;account&amp;#34; required=&amp;#34;true&amp;#34;&lt;br /&gt;binding=&amp;#34;#{loansManager.client.accountNumber}&amp;#34;&lt;br /&gt;validator=&amp;#34;#{loansManager.validateAccountNumber}&amp;#34;&lt;br /&gt;requiredMessage=&amp;#34;Value is required!&amp;#34;/&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt;&lt;br /&gt;You might as well do validation anywhere inside your application and just add the message to the &lt;span class="snippet"&gt;FacesContext&lt;/span&gt; in the same manner you've seen earlier, but this has one important constraint. In place of &lt;span class="snippet"&gt;cmp.getClientId(ctxt)&lt;/span&gt; inside&lt;br /&gt;&lt;span class="snippet"&gt;ctxt.addMessage(cmp.getClientId(ctxt), msg);&lt;/span&gt;&lt;br /&gt;you would have to hard code the component id:&lt;br /&gt;&lt;pre name="code" class="java"&gt;ctxt.addMessage("account", msg);&lt;/pre&gt;&lt;br /&gt;since you no longer have the reference to the component itself.&lt;br /&gt;Also, you might put a global message (not bound to any component) into a &lt;span class="snippet"&gt;FacesContext&lt;/span&gt; message queue with&lt;br /&gt;&lt;pre name="code" class="java"&gt;ctxt.addMessage(null, msg);&lt;/pre&gt;&lt;br /&gt;but these messages can only be displayed with &lt;span class="snippet"&gt;&amp;lt;h:messages/&amp;gt;&lt;/span&gt; element.&lt;br /&gt;&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1468532151642511496-6978630423828191221?l=thatjavathing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/6978630423828191221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thatjavathing.blogspot.com/2009/04/validators-in-jsf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/6978630423828191221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/6978630423828191221'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/2009/04/validators-in-jsf.html' title='Validators in JSF'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1468532151642511496.post-4512565976577002783</id><published>2009-04-04T11:54:00.000-07:00</published><updated>2009-04-06T01:25:15.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='java-ee'/><title type='text'>Extended Persistence Context</title><content type='html'>Extended persistence context is an interesting feature of the JPA specification. It allows one to declare that the injected &lt;span class="snippet"&gt;EntityManager&lt;/span&gt; lives beyond the scope of the JTA transaction, that is, to &lt;em&gt;extend&lt;/em&gt; it to the lifetime of the stateful session bean itself. This is achieved with the following annotation:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager em;&lt;/pre&gt;&lt;br /&gt;Doing this has a couple of implications.&lt;br /&gt;First of all, within the extended persistence context, managed entities remain managed even after the transaction commits (or is rolled back). This behavior is very different than that of a transaction scoped context, were entities get detached at the end of the transaction.&lt;br /&gt;Second implication important to note is that changes done to the managed entities from outside of a transaction will not be propagated to the database immediately, and will be buffered instead. In order to get the changes reflected in the database, the EntitiyManager needs to be accessed from a transaction context and flushed (by invoking it's &lt;span class="snippet"&gt;flush()&lt;/span&gt; method).&lt;br /&gt;&lt;br /&gt;For obvious reasons, extended persistence context is only available within stateful Session Beans.&lt;br /&gt;&lt;br /&gt;The most frequently quoted example of use is a multi-step conversation with a client, where the data that is to be persisted in a single transaction is acquired form a client in a series of steps with arbitrary periods of time in between. In this scenario, changes are sequentially applied to the managed entity in question, and the &lt;span class="snippet"&gt;EntityManager&lt;/span&gt; is flushed at the very end of the conversation.&lt;br /&gt;&lt;br /&gt;To illustrate this, image you were dealing with a multi-page client registration form. On each page, the client is expected to input some information about themselves, but each time the information pertains to a different aspect. For example, the first page could ask for general details, like name and title, the second would deal with the contact info, and the third could ask for some optional data, like an average income or a favorite hobby.&lt;br /&gt;Now, to achieve this, you could create a stateful bean similar to the following:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Stateful&lt;br /&gt;public class RegistrationBean implements Registration&lt;br /&gt;{&lt;br /&gt;   @PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager em;&lt;br /&gt;&lt;br /&gt;   private Customer customer;&lt;br /&gt;&lt;br /&gt;   public long createCustomer(String name, String lastName)&lt;br /&gt;   {&lt;br /&gt;      customer = new Customer();&lt;br /&gt;      customer.setName(name);&lt;br /&gt;      customer.setLastName(lastName);&lt;br /&gt;      em.persist(customer);&lt;br /&gt;      return customer.getId();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void setContacts(String address, String phoneNumber, String email)&lt;br /&gt;   {&lt;br /&gt;      customer.setAddress(address);&lt;br /&gt;      customer.setPhoneNumber(phoneNumber);&lt;br /&gt;      customer.setEmail(email);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void setOptionals(...)&lt;br /&gt;   {&lt;br /&gt;      ...&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;  @TransactionAttribute(TransactionAttributeType.REQUIRED)&lt;br /&gt;   public void confirmRegistration() {&lt;br /&gt;      em.flush();&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In conclusion, it's worth to note that the same effect could have been achieved by wrapping the whole conversation in a single user-managed transaction, but that it still makes more sense to exploit the power of an extended persistence context as it provides both a simpler and cleaner solution.&lt;br /&gt;&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1468532151642511496-4512565976577002783?l=thatjavathing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thatjavathing.blogspot.com/feeds/4512565976577002783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thatjavathing.blogspot.com/2009/04/extended-persistence-context.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/4512565976577002783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1468532151642511496/posts/default/4512565976577002783'/><link rel='alternate' type='text/html' href='http://thatjavathing.blogspot.com/2009/04/extended-persistence-context.html' title='Extended Persistence Context'/><author><name>veggen</name><uri>http://www.blogger.com/profile/05515187432098285483</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
