コード例 #1
1
ファイル: JPAPlugin.java プロジェクト: visan/play1
  @Override
  public Object bind(
      RootParamNode rootParamNode,
      String name,
      Class clazz,
      java.lang.reflect.Type type,
      Annotation[] annotations) {
    // TODO need to be more generic in order to work with JPASupport
    if (clazz.isAnnotationPresent(Entity.class)) {

      ParamNode paramNode = rootParamNode.getChild(name, true);

      String[] keyNames = new JPAModelLoader(clazz).keyNames();
      ParamNode[] ids = new ParamNode[keyNames.length];
      // Collect the matching ids
      int i = 0;
      for (String keyName : keyNames) {
        ids[i++] = paramNode.getChild(keyName, true);
      }
      if (ids != null && ids.length > 0) {
        try {
          EntityManager em = JPABase.getJPAConfig(clazz).getJPAContext().em();
          StringBuilder q =
              new StringBuilder().append("from ").append(clazz.getName()).append(" o where");
          int keyIdx = 1;
          for (String keyName : keyNames) {
            q.append(" o.").append(keyName).append(" = ?").append(keyIdx++).append(" and ");
          }
          if (q.length() > 4) {
            q = q.delete(q.length() - 4, q.length());
          }
          Query query = em.createQuery(q.toString());
          // The primary key can be a composite.
          Class[] pk = new JPAModelLoader(clazz).keyTypes();
          int j = 0;
          for (ParamNode id : ids) {
            if (id.getValues() == null
                || id.getValues().length == 0
                || id.getFirstValue(null) == null
                || id.getFirstValue(null).trim().length() <= 0) {
              // We have no ids, it is a new entity
              return GenericModel.create(rootParamNode, name, clazz, annotations);
            }
            query.setParameter(
                j + 1,
                Binder.directBind(
                    id.getOriginalKey(), annotations, id.getValues()[0], pk[j++], null));
          }
          Object o = query.getSingleResult();
          return GenericModel.edit(rootParamNode, name, o, annotations);
        } catch (NoResultException e) {
          // ok
        } catch (Exception e) {
          throw new UnexpectedException(e);
        }
      }
      return GenericModel.create(rootParamNode, name, clazz, annotations);
    }
    return null;
  }
コード例 #2
0
  @SuppressWarnings("unchecked")
  private void putEntityListeners(AnnotationInfo ai, EntityListeners entityListeners) {
    Class[] entityListenerClasses = entityListeners.value();
    if (entityListenerClasses == null) return;

    Map<Class, List<ClassMethodEntry>> listeners = ai.getEntityListeners();

    List<Class<? extends Annotation>> annotations =
        Arrays.asList(
            PrePersist.class,
            PreUpdate.class,
            PreRemove.class,
            PostLoad.class,
            PostPersist.class,
            PostUpdate.class,
            PostRemove.class);
    // TODO: More than one listener per event cannot be handled like this...

    for (Class clazz : entityListenerClasses) {
      //            System.out.println("class=" + clazz);
      for (Method method : clazz.getMethods()) {
        //                System.out.println("method=" + method.getName());
        for (Class<? extends Annotation> annotationClass : annotations) {
          Annotation annotation = method.getAnnotation(annotationClass);
          addListener(listeners, clazz, method, annotation, annotationClass);
        }
      }
    }
  }
コード例 #3
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 Field[] keyFields() {
   Class c = clazz;
   try {
     List<Field> fields = new ArrayList<Field>();
     while (!c.equals(Object.class)) {
       for (Field field : c.getDeclaredFields()) {
         // TODO: add cashe field->isAnnotationPresent
         if (InternalCache.isEnableAnnotationPresent()) {
           if (InternalCache.isAnnotationPresent(Id.class, field)
               || InternalCache.isAnnotationPresent(EmbeddedId.class, field)) {
             field.setAccessible(true);
             fields.add(field);
           }
         } else {
           if (field.isAnnotationPresent(Id.class)
               || field.isAnnotationPresent(EmbeddedId.class)) {
             field.setAccessible(true);
             fields.add(field);
           }
         }
       }
       c = c.getSuperclass();
     }
     final Field[] f = fields.toArray(new Field[fields.size()]);
     if (f.length == 0) {
       throw new UnexpectedException("Cannot get the object @Id for an object of type " + clazz);
     }
     return f;
   } catch (Exception e) {
     throw new UnexpectedException(
         "Error while determining the object @Id for an object of type " + clazz);
   }
 }
コード例 #4
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 public List<Model.Property> listProperties() {
   List<Model.Property> properties = new ArrayList<Model.Property>();
   Set<Field> fields = new LinkedHashSet<Field>();
   Class<?> tclazz = clazz;
   while (!tclazz.equals(Object.class)) {
     Collections.addAll(fields, tclazz.getDeclaredFields());
     tclazz = tclazz.getSuperclass();
   }
   for (Field f : fields) {
     int mod = f.getModifiers();
     if (Modifier.isTransient(mod) || Modifier.isStatic(mod)) {
       continue;
     }
     if (f.isAnnotationPresent(Transient.class)) {
       continue;
     }
     if (f.isAnnotationPresent(NoBinding.class)) {
       NoBinding a = f.getAnnotation(NoBinding.class);
       List<String> values = Arrays.asList(a.value());
       if (values.contains("*")) {
         continue;
       }
     }
     Model.Property mp = buildProperty(f);
     if (mp != null) {
       properties.add(mp);
     }
   }
   return properties;
 }
コード例 #5
0
ファイル: Audit.java プロジェクト: bgarrels/xpert-framework
  public static String getEntityName(Class entity) {

    if (mappedName.get(entity) != null) {
      return mappedName.get(entity);
    }

    String name = null;

    Table table = (Table) entity.getAnnotation(Table.class);
    if (table != null && table.name() != null && !table.name().isEmpty()) {
      name = table.name();
    } else {
      Entity entityAnnotation = (Entity) entity.getAnnotation(Entity.class);
      if (entityAnnotation != null
          && entityAnnotation.name() != null
          && !entityAnnotation.name().isEmpty()) {
        name = entityAnnotation.name();
      } else {
        name = entity.getSimpleName();
      }
    }

    mappedName.put(entity, name);

    return name;
  }
コード例 #6
0
  @Override
  public void complete() {
    AmberPersistenceUnit persistenceUnit = _sourceType.getPersistenceUnit();

    Class targetClass = getTargetClass();

    if (targetClass == null || void.class.equals(targetClass))
      throw error(
          _field,
          L.l(
              "Can't determine targetEntity for {0}.  @OneToMany properties must target @Entity beans.",
              _fieldName));

    AmberType targetType = persistenceUnit.createType(targetClass);

    if (targetType == null) {
      throw error(
          _field,
          L.l(
              "targetClass '{0}' is not a known element collection class for {1}.  The targetClass of a @ElementCollection must be a basic class.",
              targetClass.getName(), _fieldName));
    }

    /*
    if (_orderBy != null)
      calculateOrderBy(_orderBy);
    */

    addCollection(targetType);
  }
コード例 #7
0
  private Class<?> getUnwrappedClass(Class<? extends Object> class1) {
    Class<?> result = class1;

    while (null != result && result.getClass().getSimpleName().contains("$$EnhancerBy"))
      result = result.getSuperclass();

    return result;
  }
コード例 #8
0
ファイル: Audit.java プロジェクト: bgarrels/xpert-framework
 public Field getDeclaredField(Class clazz, String fieldName) throws Exception {
   Field field = clazz.getDeclaredField(fieldName);
   if (field == null
       && clazz.getSuperclass() != null
       && !clazz.getSuperclass().equals(Object.class)) {
     return getDeclaredField(clazz.getSuperclass(), fieldName);
   }
   return field;
 }
コード例 #9
0
  private void putTableDeclaration(AnnotationInfo ai, Class<?> c) {
    Table table = c.getAnnotation(Table.class);
    if (table != null) {
      if (table.name() == null)
        throw new PersistenceException("You must specify a name= for @Table on " + c.getName());

      ai.setDomainName(table.name());
    }
  }
コード例 #10
0
 /**
  * This strips the cglib class name out of the enhanced classes.
  *
  * @param c
  * @return
  */
 public static Class stripEnhancerClass(Class c) {
   String className = c.getName();
   className = stripEnhancerClass(className);
   if (className.equals(c.getName())) {
     // no change, did this to fix groovy issue
     return c;
   } else {
     c = getClass(className);
   }
   return c;
 }
コード例 #11
0
ファイル: FamPlayerSeason.java プロジェクト: antoinesd/FAM
  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();

    Class cls = this.getClass();
    int ii = 0;
    builder.append(this.getClass()).append(" [");
    for (Field f : cls.getDeclaredFields()) {
      String str = "null";
      if (f.getName().equals(PROP_CLUB)) {

        if (this.getFamClub() != null) {
          str = this.getFamClub().getLibClub();
        }
        builder.append(ii++ == 0 ? "\n" : "\n,").append(f.getName()).append(" : ").append(str);

      } else if (f.getName().equals(PROP_TEAM)) {

        if (this.getFamTeam() != null) {
          str = this.getFamTeam().getLibTeam();
        }
        builder.append(ii++ == 0 ? "\n" : "\n,").append(f.getName()).append(" : ").append(str);
      } else if (f.getName().equals(PROP_SEASON)) {

        if (this.getFamSeason() != null) {
          str = this.getFamSeason().getLibSeason();
        }
        builder.append(ii++ == 0 ? "\n" : "\n,").append(f.getName()).append(" : ").append(str);
      } else if (f.getName().equals(PROP_PLAYER)) {

        if (this.getFamPlayer() != null) {
          str = this.getFamPlayer().getDisplayName();
        }
        builder.append(ii++ == 0 ? "\n" : "\n,").append(f.getName()).append(" : ").append(str);
      } else {
        try {
          builder
              .append(ii++ == 0 ? "\n" : "\n,")
              .append(f.getName())
              .append(" : ")
              .append(f.get(this));
        } catch (IllegalArgumentException e) {
          // TODO Auto-generated catch block
          LogUtil.log("Erreur!", Level.SEVERE, e);
        } catch (IllegalAccessException e) {
          // TODO Auto-generated catch block
          LogUtil.log("Erreur!", Level.SEVERE, e);
        }
      }
    }
    builder.append("\n]");
    return builder.toString();
  }
コード例 #12
0
  public void processAction(HttpServletRequest request, HttpServletResponse response)
      throws IOException {

    System.out.println("processing test driver request ... ");

    processParams(request);
    boolean status = false;
    System.out.println("tc:" + tc);

    response.setContentType("text/plain");
    ServletOutputStream out = response.getOutputStream();
    out.println("TestCase: " + tc);

    if (tc != null) {

      try {
        Class<?> c = getClass();
        Object t = this;

        Method[] allMethods = c.getDeclaredMethods();
        for (Method m : allMethods) {
          String mname = m.getName();
          if (!mname.equals(tc.trim())) {
            continue;
          }

          System.out.println("Invoking : " + mname);
          try {
            m.setAccessible(true);
            Object o = m.invoke(t);
            System.out.println("Returned => " + (Boolean) o);
            status = new Boolean((Boolean) o).booleanValue();
            // Handle any methods thrown by method to be invoked
          } catch (InvocationTargetException x) {
            Throwable cause = x.getCause();

            System.err.format("invocation of %s failed: %s%n", mname, cause.getMessage());
          } catch (IllegalAccessException x) {
            x.printStackTrace();
          }
        }
      } catch (Exception ex) {
        ex.printStackTrace();
      }

      if (status) {
        out.println(tc + ":pass");
      } else {
        out.println(tc + ":fail");
      }
    }
  }
コード例 #13
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
    private Object makeCompositeKey(Model model) throws Exception {
      initProperties();
      Class<?> idClass = getCompositeKeyClass();
      Object id = idClass.newInstance();
      PropertyDescriptor[] idProperties = PropertyUtils.getPropertyDescriptors(idClass);
      if (idProperties == null || idProperties.length == 0)
        throw new UnexpectedException("Composite id has no properties: " + idClass.getName());
      for (PropertyDescriptor idProperty : idProperties) {
        // do we have a field for this?
        String idPropertyName = idProperty.getName();
        // skip the "class" property...
        if (idPropertyName.equals("class")) continue;
        Model.Property modelProperty = this.properties.get(idPropertyName);
        if (modelProperty == null)
          throw new UnexpectedException(
              "Composite id property missing: "
                  + clazz.getName()
                  + "."
                  + idPropertyName
                  + " (defined in IdClass "
                  + idClass.getName()
                  + ")");
        // sanity check
        Object value = modelProperty.field.get(model);

        if (modelProperty.isMultiple)
          throw new UnexpectedException(
              "Composite id property cannot be multiple: "
                  + clazz.getName()
                  + "."
                  + idPropertyName);
        // now is this property a relation? if yes then we must use its ID in the key (as per specs)
        if (modelProperty.isRelation) {
          // get its id
          if (!Model.class.isAssignableFrom(modelProperty.type))
            throw new UnexpectedException(
                "Composite id property entity has to be a subclass of Model: "
                    + clazz.getName()
                    + "."
                    + idPropertyName);
          // we already checked that cast above
          @SuppressWarnings("unchecked")
          Model.Factory factory =
              Model.Manager.factoryFor((Class<? extends Model>) modelProperty.type);
          if (factory == null)
            throw new UnexpectedException(
                "Failed to find factory for Composite id property entity: "
                    + clazz.getName()
                    + "."
                    + idPropertyName);
          // we already checked that cast above
          if (value != null) value = factory.keyValue((Model) value);
        }
        // now affect the composite id with this id
        PropertyUtils.setSimpleProperty(id, idPropertyName, value);
      }
      return id;
    }
コード例 #14
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 @Override
 public Model.Factory modelFactory(Class<? extends Model> modelClass) {
   if (modelClass.isAnnotationPresent(Entity.class)) {
     return new JPAModelLoader(modelClass);
   }
   return null;
 }
コード例 #15
0
 /**
  * @param obClass
  * @return
  */
 public static Class getClass(String obClass) {
   try {
     return Class.forName(obClass, true, ourClassLoader);
   } catch (ClassNotFoundException e) {
     throw new PersistenceException(e);
   }
 }
コード例 #16
0
 private void putEntityListeners(AnnotationInfo ai, Class c) {
   EntityListeners listeners = (EntityListeners) c.getAnnotation(EntityListeners.class);
   if (listeners != null) {
     logger.fine("Found EntityListeners for " + c + " - " + listeners);
     putEntityListeners(ai, listeners);
   }
 }
コード例 #17
0
 private static boolean isEmbeddable(String className) {
   try {
     return Class.forName(className).isAnnotationPresent(Embeddable.class);
   } catch (ClassNotFoundException e) {
     return false;
   }
 }
コード例 #18
0
 public AnnotationInfo getAnnotationInfo(Class c) {
   c = stripEnhancerClass(c);
   AnnotationInfo ai = getAnnotationInfo(c.getName());
   if (ai == null) {
     ai = putAnnotationInfo(c);
   }
   return ai;
 }
コード例 #19
0
  /**
   * Obtiene las propiedades de la entidad a la cual pertenece el DAO.
   *
   * @param object entidad a la que pertenece el DAO.
   * @param clave la entidad embebida que contiene la clave primaria
   * @return Mapa con las propiedades y los valores, el cual será utilizado para la construcción de
   *     los criterios en la ejecución de la búsqueda.
   */
  @SuppressWarnings("unchecked")
  private Map<String, Object> obtenerPropiedades(Object object, String... clave) {
    Class<T> classe = (Class<T>) object.getClass();
    Field[] fields = classe.getDeclaredFields();
    Map<String, Object> mapa = new HashMap<String, Object>(fields.length);
    for (Field field : fields) {
      Boolean isClob = Boolean.FALSE;
      Annotation[] anotaciones = field.getAnnotations();
      for (Annotation annotation : anotaciones) {
        if ("@javax.persistence.Lob()".equals(annotation.toString())
            || "@javax.persistence.Transient()".equals(annotation.toString())) {
          isClob = Boolean.TRUE;
          break;
        }
      }
      if (!isClob) {
        String fieldName = field.getName();
        String methodName =
            "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
        try {
          Method method = classe.getMethod(methodName, new Class[] {});
          Object result = method.invoke(object, new Object[] {});

          if (result != null) {
            if (clave != null && clave.length == 1) {
              mapa.put(clave[0] + "." + field.getName(), result);
            } else {
              mapa.put(field.getName(), result);
            }
          }
        } catch (RuntimeException e) {
          continue;
        } catch (NoSuchMethodException e) {
          continue;
        } catch (IllegalAccessException e) {
          continue;
        } catch (InvocationTargetException e) {
          continue;
        }
      }
    }
    return mapa;
  }
コード例 #20
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 Field keyField() {
   Class c = clazz;
   try {
     while (!c.equals(Object.class)) {
       for (Field field : c.getDeclaredFields()) {
         if (field.isAnnotationPresent(Id.class)
             || field.isAnnotationPresent(EmbeddedId.class)) {
           field.setAccessible(true);
           return field;
         }
       }
       c = c.getSuperclass();
     }
   } catch (Exception e) {
     throw new UnexpectedException(
         "Error while determining the object @Id for an object of type " + clazz);
   }
   throw new UnexpectedException("Cannot get the object @Id for an object of type " + clazz);
 }
コード例 #21
0
  public void abrirRecursivo() throws Exception {

    this.abrirEstado();

    Field[] fillos = this.getClass().getFields();

    ArrayList<Field> aFields = new ArrayList<Field>(Arrays.asList(fillos));

    for (Field field : aFields) {

      if (!field.getName().equals("id") && !field.getName().equals("willBeSaved")) {

        if ("Set".equals(field.getType().getSimpleName())) {

          Object value =
              new PropertyDescriptor(field.getName(), this.getClass()).getReadMethod().invoke(this);
          Class<? extends Set> theClass = Class.forName("java.util.Set").asSubclass(Set.class);
          Set objSet = theClass.cast(value);

          for (Object obj : objSet) {
            if (obj instanceof models.UnionSecureModel) {
              UnionSecureModel u = (UnionSecureModel) obj;
              u.abrirEstado();
              u.abrirRecursivo();
            }
          }

        } else {

          Object obj =
              new PropertyDescriptor(field.getName(), this.getClass()).getReadMethod().invoke(this);

          if (obj instanceof models.UnionSecureModel) {
            UnionSecureModel u = (UnionSecureModel) obj;
            u.abrirEstado();
            u.abrirRecursivo();
          }
        }
      }
    }
  }
コード例 #22
0
 /**
  * Obtiene las columnas de la clave primaria de la entidad.
  *
  * @param object Entidad de donde se obtendrán las columnas clave
  * @return Retorna una lista con las columnas de la clave primaria de la entidad
  */
 @SuppressWarnings("unchecked")
 protected List<String> obtenerId(Object object) {
   Class<T> classe = (Class<T>) object.getClass();
   Field[] fields = classe.getDeclaredFields();
   List<String> id = new ArrayList<String>();
   for (Field field : fields) {
     Annotation[] anotaciones = field.getAnnotations();
     for (Annotation annotation : anotaciones) {
       if ("@javax.persistence.Id()".equals(annotation.toString())) {
         id.add(field.getName());
         break;
       } else if ("@javax.persistence.EmbeddedId()".equals(annotation.toString())) {
         String fieldName = field.getName();
         String methodName =
             "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
         try {
           Method method = classe.getMethod(methodName, new Class[] {});
           Object result = method.invoke(object, new Object[] {});
           Class<T> classe1 = (Class<T>) result.getClass();
           Field[] fields1 = classe1.getDeclaredFields();
           for (Field fieldPK : fields1) {
             if (!"serialVersionUID".equals(fieldPK.getName())) {
               id.add(fieldName + "." + fieldPK.getName());
             }
           }
         } catch (RuntimeException e) {
           continue;
         } catch (NoSuchMethodException e) {
           continue;
         } catch (IllegalAccessException e) {
           continue;
         } catch (InvocationTargetException e) {
           continue;
         }
       }
     }
   }
   return id;
 }
コード例 #23
0
 public synchronized int removeAll(Class entityClass) {
   int affectedResult = 0;
   final EntityManager em = getEntityManager();
   try {
     em.getTransaction().begin();
     affectedResult = em.createQuery("DELETE FROM " + entityClass.getName()).executeUpdate();
     em.getTransaction().commit();
   } finally {
     if (em.getTransaction().isActive()) em.getTransaction().rollback();
     em.close();
   }
   return affectedResult;
 }
コード例 #24
0
 private void putMethods(AnnotationInfo ai, Class c) {
   Method[] methods = c.getDeclaredMethods();
   for (Method method : methods) {
     //            logger.fine("method=" + method.getName());
     String methodName = method.getName();
     if (!methodName.startsWith("get")) continue;
     //            System.out.println("method=" + methodName);
     if (config.isGroovyBeans()
         && (methodName.equals("getProperty") || methodName.equals("getMetaClass"))) continue;
     Transient transientM = method.getAnnotation(Transient.class);
     if (transientM != null) continue; // we don't save this one
     ai.addGetter(method);
   }
 }
コード例 #25
0
ファイル: Audit.java プロジェクト: bgarrels/xpert-framework
 public Object getAnnotadedWithId(Object object, Class clazz) {
   Field[] fields = clazz.getDeclaredFields();
   Method[] methods = clazz.getDeclaredMethods();
   try {
     for (Field field : fields) {
       if (field.isAnnotationPresent(Id.class)) {
         field.setAccessible(true);
         return field.get(object);
       }
     }
     for (Method method : methods) {
       if (method.isAnnotationPresent(Id.class)) {
         return method.invoke(object);
       }
     }
     if (clazz.getSuperclass() != null && !clazz.getSuperclass().equals(Object.class)) {
       return getAnnotadedWithId(object, clazz.getSuperclass());
     }
   } catch (Exception ex) {
     logger.log(Level.SEVERE, null, ex);
   }
   return null;
 }
 /** Return the server platform if running in JEE. */
 public static ServerPlatform getServerPlatform() {
   if (serverPlatform == null) {
     String platformClass = System.getProperty("TEST_SERVER_PLATFORM");
     if (platformClass == null) {
       serverPlatform = new JEEPlatform();
     } else {
       try {
         serverPlatform = (ServerPlatform) Class.forName(platformClass).newInstance();
       } catch (Exception notFound) {
         throw new RuntimeException(notFound);
       }
     }
   }
   return serverPlatform;
 }
コード例 #27
0
 public synchronized <T> List<T> loadAll(Class<T> entityClass, String orderBy) {
   final EntityManager em = getEntityManager();
   try {
     final TypedQuery<T> query =
         em.createQuery(
             "SELECT c FROM "
                 + entityClass.getName()
                 + "  c "
                 + ((orderBy == null) ? "" : " ORDER BY " + orderBy),
             entityClass);
     return query.getResultList();
   } finally {
     em.close();
   }
 }
コード例 #28
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 public Long count(List<String> searchFields, String keywords, String where) {
   String q = "select count(*) from " + clazz.getName() + " e";
   if (keywords != null && !keywords.equals("")) {
     String searchQuery = getSearchQuery(searchFields);
     if (!searchQuery.equals("")) {
       q += " where (" + searchQuery + ")";
     }
     q += (where != null ? " and " + where : "");
   } else {
     q += (where != null ? " where " + where : "");
   }
   Query query = getJPAContext().em().createQuery(q);
   if (keywords != null && !keywords.equals("") && q.indexOf("?1") != -1) {
     query.setParameter(1, "%" + keywords.toLowerCase() + "%");
   }
   return Long.decode(query.getSingleResult().toString());
 }
コード例 #29
0
 @Before
 public void setUp() throws Exception {
   try {
     Class.forName("org.hsqldb.jdbcDriver");
     connection = DriverManager.getConnection("jdbc:hsqldb:mem:unit-testing-jpa", "sa", "");
   } catch (Exception ex) {
     ex.printStackTrace();
     fail("Exception during HSQL database startup.");
   }
   try {
     emFactory = Persistence.createEntityManagerFactory("MyPersistence");
     em = emFactory.createEntityManager();
   } catch (Exception ex) {
     ex.printStackTrace();
     fail("Exception during JPA EntityManager instanciation.");
   }
 }
コード例 #30
0
ファイル: JPAPlugin.java プロジェクト: visan/play1
 public static Set<Field> getModelFields(Class<?> clazz) {
   Set<Field> fields = new LinkedHashSet<Field>();
   Class<?> tclazz = clazz;
   while (!tclazz.equals(Object.class)) {
     // Only add fields for mapped types
     if (tclazz.isAnnotationPresent(Entity.class)
         || tclazz.isAnnotationPresent(MappedSuperclass.class))
       Collections.addAll(fields, tclazz.getDeclaredFields());
     tclazz = tclazz.getSuperclass();
   }
   return fields;
 }