join wouldn't be appropriate, because that correlates to the is-a relationship rather than the has-a that you're describing.
If the lookup tables rarely/never change, you can go with the IntValuedEnum solution (see
http://www.hibernate.org/273.html, though that's for StringValuedEnumType.. you can infer the changes easily). Then your API would be calling setState(State.NSW). That's better than the type-unsafe "NSW", and still allows you to use the strings at a slightly higher level (by having your enum know about both the integer and string representations of each state).
If the lookup tables do change (take, for example, branch office name: you don't want the user to be able to type in any old string, but you want to be able to add company branches easily), then map the lookup table as an ordinary entity class.