I've been wanting to start this series of posts for some time now, finally I have a nice working project and can put into words what I've learned over the last months with JavaEE 7.
Now, do not expect to find here anything ground breaking, it's just my progress while I learn JavaEE 7 and many things are subject to change while I learn more. Many things are probably not done the "correct" way and lack proper functionality, but like I said it's a constant work in progress until I finalise my project. Right now for the code, I don't take into consideration false input and/or exceptions. Those will come later. Also, I may make mistakes or have misunderstood something, feel free to correct me.
Mostly I'm using the official PrimeFaces documentation, showcase and forum, various Youtube videos and of course stackoverflow.
Before we begin
Make sure you have a working persistence unit, I'm working with NetBeans 8.0.1, GlassFish 4.1 and JavaDB. I followed this fantastic guide to setup my environment and it works perfectly. I use the same User and Group tables as in the video because the users will log in to the system.
Also, what I'm showing here are from an imaginary DB admin's perspective, nonetheless any CRUD operations in any point of the application should be more or less the same.
The case here is that the admin wants to add a new user with the specified credentials, either as a normal user or as admin.
Let's take a look at the JSF code (gist here).
Well, the form is what will be submitted and its values stored to the database. The PrimeFaces panelGrid element allows us to create this really good looking grid with elements.
Its column attribute is self-explanatory and works like this; the first element (facets excluded) will be placed in the first column, the second in the second column, the third in the first column and so on. That's why I'm alternating the outputLabels and inputTexts.
The selectOneRadio element is a really useful one, we can group radio buttons and select only one of the bunch. I think this functionality isn't present in vanilla JSF, we'd have to employ JS scripts to do that. Haven't looked too much into it though, don't take my word for granted.
The inputTexts have a required=true attribute. It means that the value cannot be empty. Like in every registration form online, some fields are required and some are optional. If the attribute was set to false or not set at all, the field would be optional and could accept empty values. The requiredMessage is a simple message shown if the user tries to submit the form and leaves some inputText empty.
This is what happens if the form is submitted with a couple empty fields:
The two commandButtons process the form, the Cancel one clears the form and the CreateUser one saves the User. The commandButtons' behaviour in PrimeFaces is to update with AJAX, in this case I din't want to update with AJAX so I set the ajax attribute to false. The action attribute can be either another webpage to navigate to, or a method in the backing bean.
The messages and growl elements are a way of showing messages to the client.
JSF Backing Bean
When it comes to processing data, the webpage can't do much. So far, all we've done is set up a usual web page with JSF notation. The data must be passed to Java classes to be processed, every JSF page must have a backing bean if it deals with data. Gist can be found here.
The RequestScoped annotation is used because the backing bean will be used once per form submission and doesn't need to maintain data. I'm still a bit fuzzy on the scopes so...
The Named annotation "renames" the backing bean for ease of use. The class name could be "BoogieBoogie" or anything else but I'd rather use the createUserJSFBean name in the JSF page.
The two EJBs are the objects that will persist the data to the database, they are injected and cannot be instantiated in the constructor since the lifecycle of the EJBs is controlled by the container. They will be invoked when they're needed.
The private User and Groups objects are used to be passed as arguments in the respective EJB create methods. They aren't necessary, just useful.
The following five Strings are the actual variables that hold the values of the JSF page. They need to have getters and setters otherwise the JSF page can't access them.
Next, I have the createNewUser method which is called by the Submit commandButton. It calls the helper inputCredentials (just to set the form values to the User and Groups objects), calls the EJBs' create methods to persist the data, displays a simple Growl to show that user was created, and empties the form fields using the clearInputCredentials method.
Entity Session Beans
The session bean communicates with the database and performs queries to it. NetBeans generates some really useful classes. Gist is here.
The abstract class this one extends, has some basic functionality which is really handy. Methods for creating, editing, removing and finding entities are present in the abstract class. In this case, I'm overriding the create method because I want to add some more code.
The PasswordHasher is a helper object (it includes Google Guava) that generates SHA-256 hashes of the given password. It's not wise to leave the passwords in cleartext, some type of hash needs to be applied.
When I created the database I forgot to set the ID column to auto-generate values, so now I have to manually assign values to the ID fields of the users. That's no problem when I have the findMaxID method. It fetches the maximum value of the table's ID column and increments by 1 when I set the user's ID.
And that's it.
Coming up next...
In the next part of this guide I will show how I implemented the showing and deleting of users. Much more interesting in my opinion and a little bit of Java8 will be shown.