Engineering Insights & Enterprise solutions
Let’s say you have a Coffee object and 3 sizes for coffee (small, medium, and large). You can create a Coffee class like this
public class Coffee { private Long id; // add other propeties private CoffeeSize coffeeSize; // ... setters and getters }
and the CoffeeSize class:
public class CoffeeSize { private int id; private String name; private String i18nKey; // ... setters and getters }
But every time you load a Coffee object you execute a SQL join to load the CoffeeSize.
Of course, you can create a CoffeeSize object and define some public static final CoffeeSize objects, but with java 1.5 you can do something like this :
create a java enum named CoffeeSize and persists just the CoffeeSize id.
package coffee; import java.util.HashMap; import java.util.Map; public enum CoffeeSize { SMALL(1, "Small", "coffeeSize.small"), MEDIUM(1, "Medium", "coffeeSize.medium"), LARGE(1, "Large", "coffeeSize.large"); private int id; private String name; private String i18nKey; private static Map<Integer, CoffeeSize> coffeeSizes = new HashMap<Integer, CoffeeSize>(); static{ CoffeeSize[] coffeeSizesArray = CoffeeSize.values(); for (CoffeeSize coffeeSize : coffeeSizesArray) { coffeeSizes.put(coffeeSize.getId(), coffeeSize); } } private CoffeeSize(int id, String name, String key) { this.id = id; this.name = name; i18nKey = key; } public int getId() { return id; } public String getName() { return name; } /** * This is an i18n key defined in message.properties * @return the i18n key */ public String getI18nKey() { return i18nKey; } /** * For the id stored in database get the CoffeeSize object * @param id the id stored in database * @return the {@link CoffeeSize} object */ public static CoffeeSize getCoffeeSizeById(Integer id) { return CoffeeSize.coffeeSizes.get(id); } }
The Coffee object will look something like this (I used hibernate and ejb3 annotations):
package coffee; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; @Entity @Table(name = "coffee") public class Coffee { private Long id; // add other propeties private Integer coffeeSizeId; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getCoffeeSizeId() { return coffeeSizeId; } public void setCoffeeSizeId(Integer coffeeSizeId) { this.coffeeSizeId = coffeeSizeId; } @Transient public CoffeeSize getCoffeeSize(){ return CoffeeSize.getCoffeeSizeById(coffeeSizeId); } }
Look at the getCoffeeSize method: it is transient(is not persisted). The persisted fields are id and coffeeSizeId. You avoid a SQL join by putting private Integer coffeeSizeId instead of private CoffeeSize coffeeSize and creating a getCoffeeSize method that returns a CoffeeSize object. All the CoffeeSize objects are loaded in memory in the static map coffeeSizes.
But remember, this will work only if you don’t want to add a new size for coffee without recompiling and deploying your application.