Monday, November 12, 2007

Two Hats

So did you hear the one about 2 hats on a hat rack?

 

The first one said to the other - "You stay here, I'll go on a head."

 

get it go on a head....

Friday, November 09, 2007

H:SelectOneMenu

This is the JSF tag that causes me more frustration than just about any other tag.   Probably documented the worst - probably a relation ship there...

So here is an example of the tag:

 

<h:selectonemenu value="#{selectManager.selectedTheme}">
<a4j:support actionlistener="#{treeManager.filterWorkspaces}"
ajaxsingle="true"
rerender="workspaceTree"
event="onchange">
<f:selectitems value="#{selectManager.themes}">
</h:selectonemenu>

 


Aside from from the a4j:support tag (we'll talk about that later) it is pretty much a text book example. The problem is what happens in the selectManager. 


We have 2 values we are binding to this component one is the #{selectManager.selectedTheme} and the other is #{selectManager.themes}.  If we take a step back and remember what the HTML select/option guys do we can figure out what is going on the selectedTheme variable is going to be one Object that is submitted on the post - the tricky part is that the themes object supposedly can be a List, an Array , a Set but really you just want to use a List.  Everything else just causes problems.


So the data backing the selectOneMenu is kind of important.  The API and documentation says that you need to use SelectItem objects and when you create a new one it takes an Object and a String (there are other constrcutors but this one works good for me)in it's constructor one is the value the other is the label.  Fair enough...


Here is the really important part the Object for the value really needs to be a String.  Now you can go and jump through all kinds of hoops to write converters and modify all your config files but just make the darn thing a String and be done with it.  If you want to put in your fancy objects I wish you the best of luck but keep the complex stuff in your code not the transmission between the jsps and your controllers.


So, the a4j:support part... this is the fancy stuff that is given to us from ajax4jsf library it makes your select component make ajax calls to the bound listener (#{treeManager.filterWorkspaces}) in our case.  It submits to a method that needs to accept an ActionEvent and return nothing.  Once you get into that method it is super easy to get the selected item - notice the selectOneMenu has a bound value #{selectManager.selectedTheme} that value is updated via the DHTML it has nothing to do with AJAX or form submits anytime you change the select list that value is changed... So when you're in your event method all you have to do is ask the FacesContext what the value is something like this:

SelectManager mgr = (SelectManager)FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("selectManager");
mgr.getSelectedTheme();

 


That's it... Pretty easy huh?


-Aaron

My New Java Shirt

Check out my new Java shirt! You're probably jealous now aren't you.

Thursday, November 08, 2007

Java Server Faces and AJAX

So, to carry on the theme from the previous post I've been playing with JSF quite a bit lately.  I've recently been moved over to the Architecture team and this team isn't so Java savvy.  They do learn quickly they/we are working on a proof of concept application and they opted to do Spring MVC in lieu of Java Server Faces.  Mostly do to the very steep learning curve; they wanted to learn something fairly easy to help meet their delivery dates.  Since they don't have much of any Java experience it was probably a wise choice.

Except for the fact that the development team that they are supposedly leading doesn't use Spring MVC for anything!!!  The dev team is a strict Struts shop until the last project that I did which introduced JSF, which seemed to be a very successful experience, although a rather painful learning curve.

Having said that what exactly does it mean to have a standard if the people that should be defining don't follow it?  <- that is mostly just a complaining kind of question I suppose.

My real question is with all of the web frameworks out there (and that isn't even a comprehensive list, especially if you start looking at various JSF Implementations ) how can you ever decide what should be your company's standard?  A search of JSF at Dice dot com shows 1,605 jobs Struts has 2,318.  I'm sure there is a bit of cross over but that is a significant difference.  Supposedly JSF is the direction the industry is moving towards - in fact IBM is not longer actively supporting Struts on their portal servers, so I guess that must mean something.

So why do enterprise development teams set standards if the technology moves so quickly?  As soon as you set them they're out of date...  So why then?

  • Performance
  • Scalability
  • Stability
  • Development Speed
  • Easily found skill set
  • Licensing
  • Support Structure
  • Long term viability of the technology

I guess that is a decent list - not terribly comprehensive but things to think about when deciding on a standard.  What things would you think about?  What frameworks are standard where you work?

Monday, November 05, 2007

JPA Code Examples

So here are the goodies:

first you need to make your persistence.xml file look kind of like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="TestJPA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.agnostic.software.jpa.entities.Users</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"></property>
<property name="hibernate.connection.url" value="jdbc:mysql://serverName/dbName"></property>
<property name="hibernate.connection.username" value="webUser"></property>
<property name="hibernate.connection.password" value="myPassword"></property>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property>
</properties>
</persistence-unit>
</persistence>

 


Notice the properties section and the lack of jta-data-source tag, this will create a problem if you want to use this persistence file to deploy to the app server.


Your Entities won't need to change, they'll work the same. 


Your Junit tests can be configured lots of ways but this is how I did mine:

public class TestUsers extends TestCase {
private EntityManagerFactory emf;
private EntityManager em;
@Override
protected void setUp() throws Exception {
emf = Persistence.createEntityManagerFactory("TestJPA");
em = emf.createEntityManager();
}
public void testRetrieveUsers(){
em.getTransaction().begin();

List<Users> users = null;
try{
Query query = em.createQuery("Select u from Users u");
users = (List<Users>)query.getResultList();
} catch (Exception e){
e.printStackTrace();
}
assertNotNull(users);
for (Users u : users){
System.out.println(u);
}
System.out.println("returning: " + users.size() + " users");
em.close();
emf.close();
}
}

That is it in a nutshell, I'm surprised that this isn't documented somewhere better but here it is for your testing enjoyment... So don't give me any excuses test that code!

Testing JPA

So, I've gotten very comfortable with the whole Spring/Hibernate mashup.  I really can't think of a better way to do database transactions than using hibernate to map the database and Spring to inject the Hibernate sessions into which ever component needs it.  It is simple and it just simply works...

 

One of my favorite things about using Hibernate is the Criteria search capabilities.  Basically it is a very OO way to do simple queries - you can get kind of clever with them but for the most part simple is better.   And in my opinion if you're writing queries that can't be done with Criteria's your data model probably sucks and needs to be re-worked... like that is ever an option.

 

Anyway I've recently joined the Architecture team and I was having a conversation espousing the glory and ease of use of these criteria's when somebody popped their head up over the cube wall and said "Why would you use Criteria's anyway they're not supported by the JPA specification."

 

Which is unfortunately true... for now anyway.

 

So, my last project was with JSF which was delivered successfully but it was extremely painful.  Mostly due to IBM's horrible implementation with their 5.0 portal server - heh, yeah it was even jdk1.3 how cool is that?

 

As that project is closing off I've been thinking on some of the pain points of that my team and I went through.  This contemplation led me to SEAM which led me to EJB3 and JPA.

 

So that's twice that JPA has come up recently so I decided to start poking around and see if I can figure the new specification out.  Indeed I have lost my beloved criteria's and once again an forced to contaminate my java code with SQL like syntax.  I can live without that temporarily anyway as long as I have a robust testing model.  So far the best I've seen is integrating with Spring to do it.  But isn't EJB3 supposed to handle the IOC for me? 

 

So after more searching than their should have been I found this article that takes you to a Sun Tutorial on desktop Java so with just a little bit massaging I can now run Junit test cases with just JPA, very sweet...