Java D&D development

At a customer where I work there is a lot of Powerbuilder Development. Powerbuilder is 4GL development environment, you can quickly create simple CRUD applications with the tool. Every now and then we have discussions on it. It’s really quit funny as you can’t compare client-server development with web development or desktop applications vs web applications. The example that is always given is, how long does it take to create a simple master-detail app. Okay with the new Java web frameworks (or ruby on rails) this is also done very quickly.

With my VS.NET 2005 I have a good competitor for beating them in the client-server development area. Java however didn’t stand a chance. My DAO layer can be generated but for then building a simple Swing app, I would lose by a couple of miles. Recently I noticed the Netbeans 6 M9 however. I gave it a go and I was really amazed. I had my database ready and it took me less than 3 minutes to create a simple Master-detail Swing application. According to the documentation I could create a webstart deployement within a couple of clicks. I would say “GO SUN!!”

I do hope they will extend their default swing components palette. Sorry but the ones that are in there at the moment isn’t sufficient. Common people you don’t even have a default date picker component. Well maybe this is because the default java.util.Date in Java is just broken ๐Ÿ™‚ But just fix it, I as developer don’t like it that I have to search for these components. Just put them in their. If you compare the VS.NET 2005 controls that are available by default with the Swing components. I can see why we still aren’t that far on the desktop as on the server.

Bejug ??? Why would I ???

Today I received an email from Javapolis. They were starting advertising the upcoming new Javapolis event. On the site they also mentioned there new Javapolis DVD that was available for purchase. I noticed this was an effort from Bejug. So I got interested as I’m a Java developer ๐Ÿ™‚

Now what do you get for paying 100 euro’s to join the Bejug. They have 3 workshops per year and … Well nothing actually. You still have to pay for Javapolis and for SpringOne. Please people explain me, why would I join??? If I compare it to the Linux User Group in Leuven, they have 2 workshops a month and you pay 10 euro’s a month.
I would rather start my own Jug and do the same as the Lug of Leuven. Anybody up for it ?

Hibernate Second Level Cache

When I have to develop a more advanced web application I tend to prefer java over any other language. Ok I have to admit, I haven’t tried ruby on rails yet, but I’ll wait for Thor to finish his nice plugin for netbeans ๐Ÿ™‚
I just find that java has almost a nice architectural solution for every problem you face (server side that is). That’s also the downside, there are so many solutions out there, that for a new programmer its a bit overwhelming!

That said, I use Hibernate in almost all my projects. (hibernate being an orm and speeding up my development) As you might know Hibernate has caching built in. First level is the cache in your session, and it’s local for you. Second level cache is for performing queries that in most cases return the same result. Now in my case I created the query and passed it a long some parameters. The parameters were offcourse also hibernate mapped objects. I setup the objects to be cacheable and I set the query to be cached. But it still went to the database on every request!?! Strange it should work?!?
So I started digging and after a while found the problem, really stupid (offcourse). I generated my object model using the reverse enginering tools from hibernate. I thought I had overridden all the equals and hascodes of these objects (as you should always do), but it seemed for these objects I passed in as parameters I hadn’t done it yet.

So as I understand, hibernate puts you query in a container, along with all the parameters you pass to the query, and a reference to the resultset. So if you try to perform the query again, he checks if this is already in the map, but because my parameters always returned false when actually business wise being true. He kept on going back to the db. So you see, even the smallest most stupidest things can have a great impact on your whole thing. This case being overriding the equals and hashcode in a small (3 properties) object, made my app lose 0.3 seconds in a lot of requests.

But BUGFIX/ENHANCEMENT has been done :))

DWR

In one of my projects the user has to select a customer from a dropdown list. Problem is that the number of customers they have is much to big to prefill. So I used dwr to build a solution. The user has a dropdown from which he can choose the field he wants to query (let’s say street), he than fills in a streetname, presses the button and the list gets prefilled with the list of customers who match.

How does it work. Wel really simple ๐Ÿ™‚

In my backend I have a simple POJO Search with a method getCustomers(String searchField,String searchValue). This calls a service layer, who in turn calls a dao layer,… you know the drill. In the end the method will return a List of Customer objects. I exposed these objects in the dwr.xml configuration file. (that’s it for the java backend stuff) (nice isn’t it ๐Ÿ™‚ )

Now the javascript part is also small and handy. I had to include the dwr engine and my exposed object as javascript objects. When the user presses the button this small piece of code gets executed


Search.getCustomers(searchField,searchValue,CustomerCallBackHandler);

When the javascript gets a response back, the CustomerCallBackHandler will be executed. That looks like this


function CustomerCallBackHandler(data){

Where data is an array of Customer JSON objects. This means that in my java Customer object I have the getter/setter getId(),getName(). In javascript I can simply do data[0].id and data[0].name.

Now isn’t that nifty?! ๐Ÿ˜›

/me like

Xsd nillable

In one of my current projects we are sending data to another company. Because xml is somewhat the standard for exchanging data these days I wrote a small java app using velocity to generate the xml files. Sure I could have used Oracle’s features to create an xml file but if you use that feature you could just as well give them an ASCII file imho.

So I started by creating the xml schema (xsd). Because some fields can be empty I some nullable fields. And that’s where the issues started. We have some dateTime fields that can be null so I thought spitting out a <date /> tag or <date></date> would do the trick!!! Biep error, after some googling and reading a lot I came to the conclussion that I had to output this : <date xsi:nil=”true”/> . Stupid if you ask me, but hey it now works.

I wrote a small velocity macro that I called:

#macro( xmlempty $value $tag $cdata)
#if ($!value == "" || !$value)
< $tag xsi:nil="true"/>
#elseif ($cdata == "true")
< $tag>< ![CDATA[$!value]]>
#else
< $tag>$!value
#end
#end

Works nice I have to say. The program was straight forward, a file that contains key value pairs. The key was the velocity template, the value was the query. I ran the query, retrieved the ResultSet cursor and while iterating it for every iteration I called upon the template that merged with my UTF-8 filewriter.

What kinde surprised me was the lack of good xsd/xml editors in the opensource. I tried the ones that were bundled with our myeclipse environment but they were more a pain than a gain. (omg lame!) So in the end I installed xmlspy and asked for a testing license. I have to say they have a really good product, but who wants to pay 600 รขโ€šยฌ for an xml editor. People come on, even ms visual studio .net 2005 pro only costs 750. They also have xml support built in, for that I’m willing to pay because of the added value but not for an xml editor. There are only a couple of things I need from an xml editor.

  • xsd code completion
  • Is my xsd valid
  • Why not, with linenumber error
  • Xml code completion using the provided xsd
  • Is my xml valid
  • Why not, with linenumber error
  • Maybe an xpath,xquery and xsl features

That should be sufficient. Hmm looks like a project for the future ๐Ÿ™‚

Javapolis

I went to javapolis, I have to say, I’m glad I went. I saw a lot of old friends there. Nice to catch up what they had been doing the last couple of years. Someone even called me ‘The enemy’ because I also did dotnet. But hey I like programming and don’t want to be bound to 1 language, why constrain yourself. We as developers are so openminded, why not about the language we do it in then???

I saw some demos of flex2. Well, Adobe / Macromedia have built a nice tool, I really have to admit. I’ll be given it a test drive. I’ll also give openlaslo a go, but according to one of their ‘sales/consultants’. It is not as far yet as flex2. And I’m pro opensource, but I’m not anti closed source. There’s a big difference and if the product is worth it, I’ll pay for it. In the future I will pay for a copy of Visual Studio if I’m the express edition doesn’t furfill my needs. If you do dotnet development on windows I’ve tried sharpdevelop (on linux monodevelop) and for oss development its ok, but If I’m doing work for a client I calculate the hours it takes. Well If I can buy a product that makes me work faster why not?? For doing java development I use eclipse because thats somewhat the standard and I can work very fast in it! So there’s no problem! But for dotnet windows client development the situation is different!

Swing Labs (who sais java swing was dead?)

As many java developers I heared about the javaone session about the swing makeover. Today I stumbled upon Romain Guy’s entry on it. You should really download this quicktime movie and watch it (24 mb). If your not that java lover, do check it out as it is a makeover about a mail client and I really like the new features they add to the mail client.

Hey philip, can’t you implement this in your framework 2? It would be nice if all the mail clients will do this in the future!! Who knows if my current projects are finished, maybe I’ll implement it ๐Ÿ˜›

Dojo and Quartz

I struck a delicate point using AJAX, the response to my ajax call had things written in javascript but these didn’t get triggered by the browser. Hmmm, well as I was using the dojotoolkit I asked those guys. One simple reply, use our contentpane and set executescripts to true. I did and voila everything works like a charm. I have to admit those guys really know what they are doing. It’s one of the cleanest dhtml toolkits I’ve ever seen. Just take a look at their examples, just amazing!!! So if you have to do dhtml stuff, check it for sure!!!

I’m also using quartz for scheduling stuff in my code,I must say it really looks nice. I’ll be using this much more in all of my applications in the near future, you can be sure of that 2!!

Generics sweetness

As I wrote earlier, last week I did a presentation on Hibernate as a good speaker I investigate my subject. During my investigation I came a cross the project that is being done for the Hibernate in Action second edition. In this book they used some generics for creating the CRUD DAO objects and it really opened my eyes. For me generics was a nice to have gadget for typecasting my collections, I had no idea this could be done with it. So read and be amazed!!

You have an interface like this:

public interface GenericDAO<T , ID extends Serializable>{
    T findById(ID id, boolean lock);
    List<T> findAll();
    List<T> findByExample(T exampleInstance, String... excludeProperty);
    T makePersistent(T entity);
    void makeTransient(T entity);
    void flush();
}


you have an basic implementation of this interface:

public abstract class GenericHibernateDAO<t , ID extends Serializable> implements GenericDAO<t , ID> {
    private Class<T> persistentClass;
    private Session session;
    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }
    @SuppressWarnings("unchecked")
    public void setSession(Session s) {
        this.session = s;
    }
    protected Session getSession() {
        if (session == null)
            throw new IllegalStateException("Session has not been set on DAO before usage");
        return session;
    }
    public Class<T> getPersistentClass() {
        return persistentClass;
    }
    @SuppressWarnings("unchecked")
    public T findById(ID id, boolean lock) {
        T entity;
        if (lock)
            entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
        else
            entity = (T) getSession().load(getPersistentClass(), id);

        return entity;
    }
    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        return findByCriteria();
    }
    @SuppressWarnings("unchecked")
    public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        Example example =  Example.create(exampleInstance);
        for (String exclude : excludeProperty) {
            example.excludeProperty(exclude);
        }
        crit.add(example);
        return crit.list();
    }
    @SuppressWarnings("unchecked")
    public T makePersistent(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }
    public void makeTransient(T entity) {
        getSession().delete(entity);
    }
    public void flush() {
        getSession().flush();
    }
    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }

}

And you have a descendent of this base class

public class BillingDetailsDAOHibernate
        extends     GenericHibernateDAO<Billingdetails , Long>
        implements  BillingDetailsDAO {

    @SuppressWarnings("unchecked")
    public List<Billingdetails> findConcrete(Class concreteClass) {
        return getSession().createCriteria(concreteClass).list();
    }
}

In short the descendent tells his parent Substitute all you T with BillingDetails and your Id with Long and abracadabra you have a simple CRUD dao for your billingDetails. Now how’s that for some fancy programming.

At the moment I’m rewritting my DAO objects to return generic collections, maybe in the next refactoring cycle I’ll use this design pattern.

My bet is that with the rise of generics, we’ll see more and more design patterns that are based on generics as this is very powerfull. The example above will surely be used in more projects to come!!

No reaction about my JUG, guess nobody is interested in learning Java. ๐Ÿ™

ps sorry if wordpress f*cked up the layout, but still check it out

Java Workshop

Yesterday evening we did an internal workshop. I explained Hibernate a bit Jacob (a collegeau) also shared his experiences on the Hibernate topic as we implemented Hibernate in a totally different way. Afterwards Jacob gave a session on Spring Webflow. I have to say it’s been a while since I went to programmers workshop. Our l2u meetings are not actually coding, more setting up and explaing new stuff. But hey I’m a coder, not an administrator but as most geeks I know my way around administration as well but it’s not my core business ๐Ÿ™‚

I spend quite some time preparing the workshop, I even listened to a session of gavin himself recorded on a mp3 player. (I’ll put it up later.) I made a small example and then I did a pojo with 2 relationships to other tables. While preparing this workhop it gave me the opportunity to take a closer look at the things we don’t use in our project. .e.g. we always use HQL to retrieve our objects. Never do we use the Criteria classes way, it comes down to the same thing but it’s more Object oriented then an EJBQL like query ๐Ÿ™‚

Although Jacob his session was rather short (due to our enthousiasm) it was really interesting. I had read the spring book, but I can’t remember much from the web flow framework besides it being a continution framework. I have to say it was a lot to take at once but it’s really really nice.
As most of you might know one of the common problems in J2EE web application is that if a user starts at page A, go’s to page B, go’s to page C and then hits the back button 2 times, changes something in form A and submits it. We actually have a merge of page C with page A. This is a problem and this is where a continuation framework comes to the rescue.
It holds some kind of version of the submited paged and if you your back button a couple of times and then submit the serverside object’s state will correspond as if you had never gone any further in your workflow. You actually went back in your workflow.
He also explained that you can define flows. Let’s say you have a OrderFlow,SearchProductFlow and SearchCustomerFlow. You can start your OrderFlow and when you come to the state where the product should get added you leavy your OrderFlow and start a subflow, the SearchProductFlow. Once this flow has finished (and the user has his selected products) we return those products into the OrderFlow and we go on from the point we left it. You then go a couple of steps further and come to the point you have to select a Customer, then you start another subflow, SearchCustomerFlow,… you get the point.

I’m not quite sure, but I believe Ruby on Rails also has this feature. I bet there are more projects out there that do this, but in Java this was rather hard to do. until now offcourse

On another note I was talking to a friend of mine, I told him I was going to give a talk on Hibernate. He told me would have loved to join, but it was an internal workshop. I talked to my boss about this and kinda proposed to make a more open thing. Something like a jug. I know we have Bejug but I haven’t seen much events off them and on their site isn’t much info about them, therefor I would like to ask if any of the readers of this entry who are interested in joining such a jug would send me an email (fix dot pczone dot be). who knows if we can get a small community together we could actually do a session at least once a month. Probably in the future 1 topic per session will be done as 2 topics were really to much ๐Ÿ™‚

So Axel or Tom who’s next ๐Ÿ˜‰