Saturday, April 28, 2012

Keyword column names with Hibernate

I ran in to an interesting problem today, and I thought I might as well help pass it around. I was attempting to create a new Hibernate class for a new table I had created. One of the column names for this table was "index" - which, unfortunately, is a keyword in MySQL. So the Hibernate code I wrote looked something like this:

    @Column(name="index")
    public int getIndex() {
        return index;
    }

When I attempted to run my new code, I was getting a very uninformative error attempting to write to that table:

Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'index, blahblahotherstufffrommyquery... ' at line 2

Excellent. Perfectly clear. Yeah.

After turning on show sql and going over to MySQLWorkbench, I found that I was getting an error there too - as it turns out, the column "index" needed to be escaped with back ticks, "`index`". Why Hibernate does not do this by default, I don't know. Luckily, as it turns out, it is a fairly easy fix - just add the back ticks to the column name in the annotation, like such:

    @Column(name="`index`")
    public int getIndex() {
        return index;
    }

This makes things work much easier. Just something to bear in mind for future reference.

Friday, April 20, 2012

Moving a jQuery Date Picker

In case you haven't noticed by this point, I am a jQuery fan. It makes working with javascript about a million times easier. Every once in a while, I stumble upon a little quirk, though, that ends up sinking hours of time trying to track down. This is one of those quirks.

I needed to make use of the jQuery UI Date Picker feature. Lovely little tool for dropping in an easy date picker. However, I was also doing some other jQuery magic with it - the date picker was in a form that could be used to edit multiple different instances on the page. I had it start out as hidden, then move it to the appropriate location and show it. Here is the code:
function moveEditForm(newLocation) {
    $('#my-edit-form').remove().insertAfter(newLocation).show();
}

There was one problem - the date picker, which I initialized on page load, would no longer open up the calendar. Took me forever to figure out why, as there was no javascript errors, nothing at all to indicate a problem. As it turns out, if you remove an initialized date picker from the page, and then add it back in somewhere else, the date picker functionality gets all foobarred.

With a little experimentation, I found that what I had to do was destroy the date picker before removing it from the page, then re-init it after I inserted it back in. The updated code looked more like this:
function moveEditForm(newLocation) {
    $( "#my-datepicker" ).datepicker("destroy");
    $('#my-edit-form').remove().insertAfter(newLocation).show();
    $( "#my-datepicker" ).datepicker();
}

I don't know why it messes up when that happens, but regardless, this patches it back up again.

Tuesday, April 17, 2012

Just a quick update

Once again, an extraordinary amount of time has passed since my last post. This time, though, I have a really good excuse - in that time, I have switched jobs, and it's taken a while for me to get back into a normal pattern. I am still developing in Java, but now solely as a web service backend, working with a flex frontend.

Learning to code in flex has been very interesting to say the least. Some of the things that are so annoying to get right in other platforms are just an easy, simple tag in flex. Of course, as with anything else, there are drawbacks. There can be times when something messes up in flex for no particular reason, and it takes forever to track down, eating up a good chunk of the productivity gained from the easy nature of flex. Also, there is some concern about the portability to other platforms, though we have not experienced that as of yet. So far, I'm fairly happy with the new processes.

One big change with this new job is that I have switched away from using Eclipse, and I now use Intellij IDEA full time. The difference in my productivity has been remarkable. IDEA is not free, which is a big drawback compared to Eclipse, but in my mind the cost is easily worth it. Particularly for development in multiple languages - IDEA intelligently handles Java, Flex, PHP and Javascript practically out of the box, with all the normal IDE bells and whistles, such as code completion, go to function definition, etc. Eclipse can do these things, but it always seemed to take a huge amount of effort to get it to work properly with any language other than Java. If you've never tried IDEA, I highly recommend you go give it a shot. They have a 30 day free trial.

Anyway, that's the state of things. Hopefully I can get back into writing a few more posts now and then. Thanks for reading!

Monday, November 14, 2011

Passwords

I remember, when I first started this blog, I said to myself that I wanted to make at least one post a week. When that started slipping, I promised myself to stick to at least once per month. I was shocked the other day when I noticed that I hadn't posted anything since July! I've been slacking off!

Well, not really. I just hit one of those stretches where things have just been flat out swamped. In that time, though, I have been experimenting with some pretty cool stuff.One neat combination of tools that I have found particularly useful is KeePass (KeePassX for Linux users) and Dropbox.

KeePass, if you are unfamiliar, is a password management solution. It stores usernames and passwords for you, so you don't have to remember them all. The password database is itself password protected, so that you only have to remember a single password instead of 37 million different passwords.

If you have used KeePass before, it is very possible that you are familiar with one of the biggest headaches of it. When you go to log in to something that requires a password, you have to go and open up KeePass, find the correct entry, right click, copy username, back to your form, paste username, repeat for password, go bang head against wall in boredom - you know, the usual.

One of the best features of KeePass, though, is also one that I find very few people actually are aware of - the global auto-type functionality. This makes it so that, as long as KeePass is running, you just have to hit the special key combo, and KeePass will automatically type in the correct username and password into the fields for you. It does this by matching the title of the window currently open with the title field inside of KeePass. If multiple entries match, it will give you a popup window allowing you to choose the correct one.

With this extra functionality in hand (it is amazing what reading through the manual of your tools will lead to!), KeePass transformed for me from a semi-useful tool that I could sometimes use, to an indispensable service that I use all the time. I turned off the password remembering features of all my browsers, and stored everything in KeePass instead. Access to any site is now only three key presses away, and I never have to worry about remembering the right passwords for things. Also, if my computer were to be stolen, the thief wouldn't have immediate access to everything. So long as I use a sufficiently difficult password, all of the rest of my identity is safe.

Aha, I can hear the naysayers among you even now. What if you are on a different computer? How do you keep this password database in sync? Well, my friend, that is where Dropbox comes in to play.

Dropbox is an application that can keep files synchronized across multiple systems. You can get a free account that will give you up to 2G of storage. So I just put my database in my Dropbox folder, and I install Dropbox on both my work and home computers, and now I have access to my database in both places. You can even, if you choose, put the database file in the Public Dropbox directory that they give you, which automatically gives the file a public URL that you can access from any device with an internet connection. This literally gives you access to your database from anywhere.

The final nail in the coffin for me was when I found out that all this was available on my iPhone as well. I use the Dropbox app and the MiniKeePass app, and I get the same access to my passwords from my phone as I do from a computer.

Anyway, I understand that this post feels more like a sales post than an informative post, but I thought it was a good way to get my feet wet again. It also helps just a little to spread the word about an app combo that has become indispensable to me in my everyday life.

Monday, July 11, 2011

Mocking LDAP Servers for JUnit

As I have gone over before, I am a fan of unit testing. The list of benefits is quite extensive. However, one of the chief hurdles of unit testing is "I don't know how to test that...". I ran into just such a problem the other day. I have a project that utilizes an LDAP server for it's back end datastore. While support for databases in unit tests is a fairly flushed out field, support for LDAP servers is not-so-much.

Luckily, though, the good people over at UnboundID have a good solution to help us out. Their LDAP SDK for Java has been a very handy tool I have used for quite a while for handling all of my LDAP connections. Recently, with their 2.1.0 release, they unveiled a new feature specifically for this issue - the in-memory directory server. However, attempting to implement this in-memory server was a little bit more challenging than the documentation would make it seem. There are just a few gotchas to be aware of.

The documentation does contain an example that shows the java code you need to get going on this. The part that is tricky, though, is this line:
server.initializeFromLDIF(true, "/tmp/test.ldif");
There are a couple of problems here. First off, it is, well, wrong. The actual method name is not initializeFromLDIF, but rather importFromLDIF. So it should look like:
server.importFromLDIF(true, "/tmp/test.ldif");
The second, and slightly more significant problem, is that there is no documentation on exactly what needs to go into test.ldif. You are left to figure that one out on your own.

The ldif file that you use to import MUST contain the definition for whatever value you specify as the base DN in the InMemoryDirectoryServerConfig constructor. It may not contain any definitions of the parents of the base DN (which makes sense, being the BASE DN), and it may not specify the definition of further children without specifying the definition of the base DN.

So, to go along with the example, here is a sample LDIF you can use to get you started:
dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example
That is the minimum required definition of the base DN. Note that the following LDIF does NOT work:
dn: dc=com
objectClass: top
objectClass: domain
dc: com

dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example

If you want to specify any further branches, that may be done in the same LDIF file, so long as you still include the top portion as above. For example, if you have a People and a Groups branch, your initial LDIF may look something like this:
dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example

dn: ou=People,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Groups

So, that covers the simple example test case, but I'm guessing that is not enough for most people. More than likely, you already have a real LDAP server out there, and you are wanting to mimic that server in your In Memory instance, so you can test in an environment that matches your production environment.

That is not necessarily apparently easy right off the bat. You need to replicate your server's schema into the in memory one, replicate all of the branches that you use, and pull in some real data to test with.

As it turns out, replicating your existing server is not too terribly complicated. If you happen to have an LDIF file that defines your server's schema on hand, you can include that into your project, and the following code should load it up:
InputStream schemaLdif = this.getClass().getClassLoader().getResourceAsStream("schema.ldif");
Entry schemaEntry = new Entry(IOUtils.toString(schemaLdif, "UTF-8"));
Schema newSchema = new Schema(schemaEntry);
config.setSchema(newSchema);
The above lines would be inserted into the sample code from the UnboundID website, before the call to the InMemoryDirectoryServer constructor. Note that I have not actually performed the above method myself, as I do not have my server's schema LDIF handy.

For me, and many others out there, you may not have access to the schema LDIF file of your server. Luckily, their is an easier way. First you must actually make a connection to your server, so that you have an LDAPConnection object pointing to it. Then you use the following code snippet:
LDAPConnection connection = //however you get your connection object
newSchema = Schema.getSchema(connection);
config.setSchema(newSchema);
The advantages to this method are that you always have the most up to date server schema, and you don't have to worry about tracking down and storing a hard copy of your server's current schema. The down sides to this method are the dependence on your server being up and available, and it is a little slow - my testing took about 6-7 seconds to retrieve the schema.

Storing the schema you retrieve from the server in a static variable can help with the performance bite, as it would only have that 6-7 second delay for your first test. However, there is nothing you can do about the dependence on the external system when utilizing this method, so that is a personal choice you have to make.

Once you have the schema loaded, you still need to import the above LDIF file for your base DN, as well as any test data you might have. All of that can be accomplished with the above importFromLDIF call. Since you should be matching your server's schema exactly, you should be able to just export records directly from your server into an LDIF file, and import them directly into your in memory server.

Once you do that, you should be good to go, ready to execute your tests against a clean, save, local environment.