Inspired by http://wicketinaction.com/2008/09/building-a-smart-entitymodel/ I created an EntityModel based on JPA annotations. Maybe this is helpful for somebody with the same question.
Any suggestions to improve the code? EntityModel.java --------------------------------------------------------------------------- import com.helmbold.util.AnnotationReader; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.logging.Level; import java.util.logging.Logger; import javax.persistence.EntityNotFoundException; import org.apache.wicket.model.IModel; public abstract class EntityModel<T> implements IModel { private transient T entity; private Class entityClass; private Serializable entityId; public EntityModel(T entity) { this.entity = entity; entityClass = entity.getClass(); } public EntityModel(Class<? extends T> entityClass, Serializable entityId) { this.entityClass = entityClass; this.entityId = entityId; } @Override public T getObject() { if (entity == null) { if (entityId != null) load(); } return entity; } @Override public void detach() { if (entity != null) { // prevent null out before entity is persisted if (getEntityId() != null) { entityId = getEntityId(); entity = null; } } } private void load() { entity = load(entityClass, this.entityId); if (entity == null) throw new EntityNotFoundException("Entity " + entityId + " of type"+ entityClass + " not found."); } protected abstract T load(Class entityClass, Serializable entityId); public void setObject(T object) { throw new UnsupportedOperationException(getClass() + "setObject(T entity) is not supported."); } private Serializable getEntityId() { Object id = null; try { id = AnnotationReader.getAnnotatedValue(entity, entityClass); } catch (IllegalArgumentException ex) { Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(EntityModel.class.getName()).log(Level.SEVERE, null, ex); } return (Serializable) id; } } --------------------------------------------------------------------------- AnnotationReader.java --------------------------------------------------------------------------- package com.helmbold.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class AnnotationReader { /** * Inspects the given object and looks first for a field with the given * annotation and, if no such field was found, for a method with the given * annotation. This is a convinience method that invokes * getAnnotatedFieldValue and invokeAnnotatedMethod. * * @param inspectedObject The object to inspect. * @param annotationType Searched annotation. * @return Value of the annotated field or return value of the annotated * method or null, if no such field or method were found. * @throws java.lang.IllegalArgumentException * @throws java.lang.IllegalAccessException * @throws java.lang.reflect.InvocationTargetException */ public static Object getAnnotatedValue( Object inspectedObject, Class annotationType) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { Object value = getAnnotatedFieldValue(inspectedObject, annotationType); if (value != null) return value; return invokeAnnotatedMethod(inspectedObject, annotationType); } /** * Inspects the given object and looks for a field with the given annotation. * If such a field is not found in the class of the current object, the search * will be continued recursivly in the super classes. The * search will be stopped when the first match was found. * * @param inspectedObject The object to inspect. * @param annotationType Searched annotation. * @return Value of the annotated field or null, if no such field was found. * @throws java.lang.IllegalArgumentException * @throws java.lang.IllegalAccessException */ public static Object getAnnotatedFieldValue( Object inspectedObject, Class annotationType) throws IllegalArgumentException, IllegalAccessException { if(inspectedObject == null) throw new NullPointerException("inspectedObject must not be null."); if(annotationType == null) throw new NullPointerException("annotationType must not be null."); return getAnnotatedFieldValue( inspectedObject.getClass(), inspectedObject, annotationType); } private static Object getAnnotatedFieldValue( Class inspectedClass, Object inspectedObject, Class annotationType) throws IllegalArgumentException, IllegalAccessException { Field[] fields = inspectedClass.getDeclaredFields(); if(fields != null){ Field.setAccessible(fields, true); for(Field f : fields) { if(f.isAnnotationPresent(annotationType)) return f.get(inspectedObject); } } Class superClass = inspectedClass.getSuperclass(); if (superClass != null) getAnnotatedFieldValue(superClass, inspectedObject, annotationType); return null; } /** * <p>Inspects the given object and looks for a method with the given * annotation. If such a method is not found in the class of the current * object, the search will be continued recursivly in the super classes. The * search will be stopped when the first match was found.</p> * * <p>Only public, parameterless methods will be invoked.</p> * * @param inspectedObject The object to inspect. * @param annotationType Searched annotation. * @return Return value of the annotated method or null, if no such method * was found. * @throws java.lang.IllegalArgumentException * @throws java.lang.IllegalAccessException * @throws java.lang.reflect.InvocationTargetException */ public static Object invokeAnnotatedMethod( Object inspectedObject, Class annotationType) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return invokeAnnotatedMethod( inspectedObject.getClass(), inspectedObject, annotationType); } private static Object invokeAnnotatedMethod( Class inspectedClass, Object inspectedObject, Class annotationType) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { Method[] methods = inspectedClass.getDeclaredMethods(); for(Method method : methods) { if(method.isAnnotationPresent(annotationType)) return method.invoke(inspectedObject); } Class superClass = inspectedClass.getSuperclass(); if (superClass != null) invokeAnnotatedMethod(superClass, inspectedObject, annotationType); return null; } } --------------------------------------------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org