@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; }
private void saveAndCascade(boolean willBeSaved) { this.willBeSaved = willBeSaved; if (avoidCascadeSaveLoops.get().contains(this)) { return; } else { avoidCascadeSaveLoops.get().add(this); if (willBeSaved) { PlayPlugin.postEvent("JPASupport.objectUpdated", this); } } // Cascade save try { Set<Field> fields = new HashSet<Field>(); Class clazz = this.getClass(); while (!clazz.equals(JPABase.class)) { Collections.addAll(fields, clazz.getDeclaredFields()); clazz = clazz.getSuperclass(); } for (Field field : fields) { field.setAccessible(true); if (Modifier.isTransient(field.getModifiers())) { continue; } boolean doCascade = false; if (field.isAnnotationPresent(OneToOne.class)) { doCascade = cascadeAll(field.getAnnotation(OneToOne.class).cascade()); } if (field.isAnnotationPresent(OneToMany.class)) { doCascade = cascadeAll(field.getAnnotation(OneToMany.class).cascade()); } if (field.isAnnotationPresent(ManyToOne.class)) { doCascade = cascadeAll(field.getAnnotation(ManyToOne.class).cascade()); } if (field.isAnnotationPresent(ManyToMany.class)) { doCascade = cascadeAll(field.getAnnotation(ManyToMany.class).cascade()); } if (doCascade) { Object value = field.get(this); if (value == null) { continue; } if (value instanceof PersistentMap) { if (((PersistentMap) value).wasInitialized()) { for (Object o : ((Map) value).values()) { if (o instanceof JPABase) { ((JPABase) o).saveAndCascade(willBeSaved); } } } continue; } if (value instanceof PersistentCollection) { if (((PersistentCollection) value).wasInitialized()) { for (Object o : (Collection) value) { if (o instanceof JPABase) { ((JPABase) o).saveAndCascade(willBeSaved); } } } continue; } if (value instanceof HibernateProxy && value instanceof JPABase) { if (!((HibernateProxy) value).getHibernateLazyInitializer().isUninitialized()) { ((JPABase) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation()) .saveAndCascade(willBeSaved); } continue; } if (value instanceof JPABase) { ((JPABase) value).saveAndCascade(willBeSaved); continue; } } } } catch (Exception e) { throw new UnexpectedException("During cascading save()", e); } }