@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; }
/** * Gets all the annotation info for a particular class and puts it in our annotation info cache. * * @param c * @return */ public AnnotationInfo putAnnotationInfo(Class c) { { Entity entity = (Entity) c.getAnnotation(Entity.class); if (entity == null) { throw new PersistenceException("Class not marked as an @Entity: " + c.getName()); } } AnnotationInfo ai = new AnnotationInfo(); ai.setClassAnnotations(c.getAnnotations()); ai.setMainClass(c); Class superClass = c; Class rootClass = null; while ((superClass = superClass.getSuperclass()) != null) { MappedSuperclass mappedSuperclass = (MappedSuperclass) superClass.getAnnotation(MappedSuperclass.class); Entity entity = (Entity) superClass.getAnnotation(Entity.class); Inheritance inheritance = (Inheritance) superClass.getAnnotation(Inheritance.class); if (mappedSuperclass != null || entity != null) { putProperties(ai, superClass); putMethods(ai, superClass); if (entity != null) { rootClass = superClass; } putEntityListeners(ai, superClass); } } if (rootClass != null) { ai.setRootClass(rootClass); DiscriminatorValue dv = (DiscriminatorValue) c.getAnnotation(DiscriminatorValue.class); String discriminatorValue; if (dv != null) { discriminatorValue = dv.value(); if (discriminatorValue == null) { throw new PersistenceException( "You must specify a value= for @DiscriminatorValue on " + c.getName()); } } else { discriminatorValue = c.getSimpleName(); } ai.setDiscriminatorValue(discriminatorValue); discriminatorMap.put(discriminatorValue, ai); } else { ai.setRootClass(c); } putTableDeclaration(ai, c); putProperties(ai, c); putMethods(ai, c); if (ai.getIdMethod() == null) { throw new PersistenceException("No ID method specified for: " + c.getName()); } putEntityListeners(ai, c); getAnnotationMap().put(c.getName(), ai); return ai; }
/** * 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; }
@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); }
public AnnotationInfo getAnnotationInfo(Class c) { c = stripEnhancerClass(c); AnnotationInfo ai = getAnnotationInfo(c.getName()); if (ai == null) { ai = putAnnotationInfo(c); } return ai; }
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()); } }
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; }
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; }
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(); } }
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()); }
@SuppressWarnings("unchecked") public List<Model> fetch( int offset, int size, String orderBy, String order, List<String> searchFields, String keywords, String where) { String q = "from " + clazz.getName(); 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 : ""); } if (orderBy == null && order == null) { orderBy = "id"; order = "ASC"; } if (orderBy == null && order != null) { orderBy = "id"; } if (order == null || (!order.equals("ASC") && !order.equals("DESC"))) { order = "ASC"; } q += " order by " + orderBy + " " + order; Query query = getJPAContext().em().createQuery(q); if (keywords != null && !keywords.equals("") && q.indexOf("?1") != -1) { query.setParameter(1, "%" + keywords.toLowerCase() + "%"); } query.setFirstResult(offset); query.setMaxResults(size); return query.getResultList(); }
public void deleteAll() { getJPAContext().em().createQuery("delete from " + clazz.getName()).executeUpdate(); }
@Override public void onApplicationStart() { // must check and configure JPA for each DBConfig for (DBConfig dbConfig : DB.getDBConfigs()) { // check and enable JPA on this config // is JPA already configured? String configName = dbConfig.getDBConfigName(); if (JPA.getJPAConfig(configName, true) == null) { // must configure it // resolve prefix for hibernate config.. // should be nothing for default, and db_<name> for others String propPrefix = ""; if (!DBConfig.defaultDbConfigName.equalsIgnoreCase(configName)) { propPrefix = "db_" + configName + "."; } List<Class> classes = findEntityClassesForThisConfig(configName, propPrefix); if (classes == null) continue; // we're ready to configure this instance of JPA final String hibernateDataSource = Play.configuration.getProperty(propPrefix + "hibernate.connection.datasource"); if (StringUtils.isEmpty(hibernateDataSource) && dbConfig == null) { throw new JPAException( "Cannot start a JPA manager without a properly configured database" + getConfigInfoString(configName), new NullPointerException("No datasource configured")); } Ejb3Configuration cfg = new Ejb3Configuration(); if (dbConfig.getDatasource() != null) { cfg.setDataSource(dbConfig.getDatasource()); } if (!Play.configuration .getProperty(propPrefix + "jpa.ddl", Play.mode.isDev() ? "update" : "none") .equals("none")) { cfg.setProperty( "hibernate.hbm2ddl.auto", Play.configuration.getProperty(propPrefix + "jpa.ddl", "update")); } String driver = null; if (StringUtils.isEmpty(propPrefix)) { driver = Play.configuration.getProperty("db.driver"); } else { driver = Play.configuration.getProperty(propPrefix + "driver"); } cfg.setProperty("hibernate.dialect", getDefaultDialect(propPrefix, driver)); cfg.setProperty("javax.persistence.transaction", "RESOURCE_LOCAL"); cfg.setInterceptor(new PlayInterceptor()); // This setting is global for all JPAs - only configure if configuring default JPA if (StringUtils.isEmpty(propPrefix)) { if (Play.configuration.getProperty(propPrefix + "jpa.debugSQL", "false").equals("true")) { org.apache.log4j.Logger.getLogger("org.hibernate.SQL").setLevel(Level.ALL); } else { org.apache.log4j.Logger.getLogger("org.hibernate.SQL").setLevel(Level.OFF); } } // inject additional hibernate.* settings declared in Play! configuration Properties additionalProperties = (Properties) Utils.Maps.filterMap(Play.configuration, "^" + propPrefix + "hibernate\\..*"); // We must remove prefix from names Properties transformedAdditionalProperties = new Properties(); for (Map.Entry<Object, Object> entry : additionalProperties.entrySet()) { Object key = entry.getKey(); if (!StringUtils.isEmpty(propPrefix)) { key = ((String) key).substring(propPrefix.length()); // chop off the prefix } transformedAdditionalProperties.put(key, entry.getValue()); } cfg.addProperties(transformedAdditionalProperties); try { // nice hacking :) I like it.. Field field = cfg.getClass().getDeclaredField("overridenClassLoader"); field.setAccessible(true); field.set(cfg, Play.classloader); } catch (Exception e) { Logger.error( e, "Error trying to override the hibernate classLoader (new hibernate version ???)"); } for (Class<?> clazz : classes) { cfg.addAnnotatedClass(clazz); if (Logger.isTraceEnabled()) { Logger.trace("JPA Model : %s", clazz); } } String[] moreEntities = Play.configuration.getProperty(propPrefix + "jpa.entities", "").split(", "); for (String entity : moreEntities) { if (entity.trim().equals("")) { continue; } try { cfg.addAnnotatedClass(Play.classloader.loadClass(entity)); } catch (Exception e) { Logger.warn("JPA -> Entity not found: %s", entity); } } for (ApplicationClass applicationClass : Play.classes.all()) { if (applicationClass.isClass() || applicationClass.javaPackage == null) { continue; } Package p = applicationClass.javaPackage; Logger.info("JPA -> Adding package: %s", p.getName()); cfg.addPackage(p.getName()); } String mappingFile = Play.configuration.getProperty(propPrefix + "jpa.mapping-file", ""); if (mappingFile != null && mappingFile.length() > 0) { cfg.addResource(mappingFile); } if (Logger.isTraceEnabled()) { Logger.trace("Initializing JPA" + getConfigInfoString(configName) + " ..."); } try { JPA.addConfiguration(configName, cfg); } catch (PersistenceException e) { throw new JPAException( e.getMessage() + getConfigInfoString(configName), e.getCause() != null ? e.getCause() : e); } } } // must look for Entity-objects referring to none-existing JPAConfig List<Class> allEntityClasses = Play.classloader.getAnnotatedClasses(Entity.class); for (Class clazz : allEntityClasses) { String configName = Entity2JPAConfigResolver.getJPAConfigNameForEntityClass(clazz); if (JPA.getJPAConfig(configName, true) == null) { throw new JPAException( "Found Entity-class (" + clazz.getName() + ") referring to none-existing JPAConfig" + getConfigInfoString(configName) + ". " + "Is JPA properly configured?"); } } }