Tuesday, October 24, 2006

A Sane Way of Using EJB3 Named Queries

Start off by putting the @NamedQuery annotation on your entity class


Then add a corresponding entry to your NamedQueries class along with a comment. You'll notice that the value of the constant is the named attribute we provided to the @NamedQuery annotation above.


The end result of these is that named queries 1) will never be mistyped, and 2) provide handy context help to remind you which parameters need to be added:

Saturday, October 21, 2006

10 Minutes With BIND

Today I decided to spend a little time getting a nameserver set up for my local network, because typing IP addresses is annoying. To my surprise, BIND is installed on FreeBSD systems by default so I got to forego that step and move straight to the juicy stuff.

Configuration is extremely simple, at least for a basic configuration like mine. I dove into this article and followed along into my named.conf file:

zone "example.net" {
type master;
file "master/example.net";
};

zone "0.168.192.in-addr.arpa" {
type master;
file "master/0.168.192.in-addr.arpa";
};


This sets up two "zones": one for normal name lookups and one for reverse, IP lookups. I simply added a few hosts to each file and set my resolver to use the server.

example.net:
...
; Machines
IN A 192.168.0.102
router IN A 192.168.0.1
zoidberg IN A 192.168.0.102
fry IN A 192.168.0.100

; Aliases
www IN CNAME @


0.168.192.in-addr.arpa:
...
1 IN PTR router.example.net.
100 IN PTR fry.example.net.
102 IN PTR zoidberg.example.net.

Since I use DHCP, I had to find a way to use my new name server while not making my entire LAN dependent upon it as a result of pointing to it from my router. The solution is to add the following options to your /etc/dhclient.conf file:

upersede domain-name "example.net";
#for the dns machine:
prepend domain-name-servers 127.0.0.1;
# for other clients:
prepend domain-name-servers 192.168.0.102;



The result is that I can now use "nice" names on my local network.

Monday, October 09, 2006

EJB3 Entity Callbacks for Password Fields

After about an hour of pounding my head over how I can automatically encode a stored password after it has been modified I came up with what I think is a pretty clever solution (though hopefully not the best, let me know if you know a better one that doesn't involve stored procedures!):

@Entity
public class Member {
Integer id;
String username;
String password;
...
transient boolean hasPasswordChanged;

@PrePersist void beforeInsert() {
if( hasPasswordChanged ) {
password = encode( password );
hasPasswordChanged = false;
}
}
public void setPassword(String password) {
hasPasswordChanged = true;
this.password = password;
}
...
}

The function tagged with the PrePersist annotation is called before the entity manager persists an entity to the data source. This is the ideal time to perform operations like this. The 'transient' field simply means that the value will not be serialized or persisted to the database.