List of usage examples for javax.persistence EntityManager merge
public <T> T merge(T entity);
From source file:gov.osti.services.Metadata.java
/** * Handle SUBMIT workflow logic.//from w ww. j av a 2 s. c om * * @param json JSON String containing the METADATA object to SUBMIT * @param file (optional) a FILE associated with this METADATA * @param fileInfo (optional) the FILE disposition information, if any * @param container (optional) a CONTAINER IMAGE associated with this METADATA * @param containerInfo (optional) the CONTAINER IMAGE disposition information, if any * @return an appropriate Response object to the caller */ private Response doSubmit(String json, InputStream file, FormDataContentDisposition fileInfo, InputStream container, FormDataContentDisposition containerInfo) { EntityManager em = DoeServletContextListener.createEntityManager(); Subject subject = SecurityUtils.getSubject(); User user = (User) subject.getPrincipal(); try { validateUploads(fileInfo, containerInfo); DOECodeMetadata md = DOECodeMetadata.parseJson(new StringReader(json)); Long currentCodeId = md.getCodeId(); boolean previouslySaved = false; if (currentCodeId != null) { DOECodeMetadata emd = em.find(DOECodeMetadata.class, currentCodeId); if (emd != null) previouslySaved = Status.Saved.equals(emd.getWorkflowStatus()); } // lookup Announced Snapshot status TypedQuery<MetadataSnapshot> querySnapshot = em .createNamedQuery("MetadataSnapshot.findByCodeIdAndStatus", MetadataSnapshot.class) .setParameter("codeId", currentCodeId).setParameter("status", DOECodeMetadata.Status.Announced); List<MetadataSnapshot> results = querySnapshot.setMaxResults(1).getResultList(); if (results.size() > 0) { log.error("Cannot Submit, Previously Announced: " + currentCodeId); return ErrorResponse.internalServerError( "This record was previously Announced to E-Link, if you need to update the metadata, please change your endpoint to \"/announce.\"") .build(); } em.getTransaction().begin(); performDataNormalization(md); // set the ownership and workflow status md.setOwner(user.getEmail()); md.setWorkflowStatus(Status.Submitted); md.setSiteOwnershipCode(user.getSiteId()); // store it store(em, md, user); // re-attach metadata to transaction in order to store any changes beyond this point md = em.find(DOECodeMetadata.class, md.getCodeId()); // if there's a FILE associated here, store it String fullFileName = ""; if (null != file && null != fileInfo) { try { fullFileName = writeFile(file, md.getCodeId(), fileInfo.getFileName(), FILE_UPLOADS); md.setFileName(fullFileName); } catch (IOException e) { log.error("File Upload Failed: " + e.getMessage()); return ErrorResponse.internalServerError("File upload failed.").build(); } } // if there's a CONTAINER IMAGE associated here, store it String fullContainerName = ""; if (null != container && null != containerInfo) { try { fullContainerName = writeFile(container, md.getCodeId(), containerInfo.getFileName(), CONTAINER_UPLOADS); md.setContainerName(fullContainerName); } catch (IOException e) { log.error("Container Image Upload Failed: " + e.getMessage()); return ErrorResponse.internalServerError("Container Image upload failed.").build(); } } // check validations for Submitted workflow List<String> errors = validateSubmit(md); if (!errors.isEmpty()) { // generate a JSONAPI errors object return ErrorResponse.badRequest(errors).build(); } // create OSTI Hosted project, as needed try { // process local GitLab, if needed processOSTIGitLab(md); } catch (Exception e) { log.error("OSTI GitLab failure: " + e.getMessage()); return ErrorResponse.internalServerError("Unable to create OSTI Hosted project: " + e.getMessage()) .build(); } // send this file upload along to archiver if configured try { // if no file/container, but previously Saved with a file/container, we need to attach to those streams and send to Archiver if (previouslySaved) { if (null == file && !StringUtils.isBlank(md.getFileName())) { java.nio.file.Path destination = Paths.get(FILE_UPLOADS, String.valueOf(md.getCodeId()), md.getFileName()); fullFileName = destination.toString(); file = Files.newInputStream(destination); } if (null == container && !StringUtils.isBlank(md.getContainerName())) { java.nio.file.Path destination = Paths.get(CONTAINER_UPLOADS, String.valueOf(md.getCodeId()), md.getContainerName()); fullContainerName = destination.toString(); container = Files.newInputStream(destination); } } // if a FILE or CONTAINER was sent, create a File Object from it File archiveFile = (null == file) ? null : new File(fullFileName); File archiveContainer = null; //(null==container) ? null : new File(fullContainerName); if (DOECodeMetadata.Accessibility.CO.equals(md.getAccessibility())) // if CO project type, no need to archive the repo because it is local GitLab sendToArchiver(md.getCodeId(), null, archiveFile, archiveContainer); else sendToArchiver(md.getCodeId(), md.getRepositoryLink(), archiveFile, archiveContainer); } catch (IOException e) { log.error("Archiver call failure: " + e.getMessage()); return ErrorResponse.internalServerError("Unable to archive project.").build(); } // send to DataCite if needed (and there is a RELEASE DATE set) if (null != md.getDoi() && null != md.getReleaseDate()) { try { DataCite.register(md); } catch (IOException e) { // tell why the DataCite registration failed log.warn("DataCite ERROR: " + e.getMessage()); return ErrorResponse.internalServerError( "The DOI registration service is currently unavailable, please try to submit your record later. If the issue persists, please contact doecode@osti.gov.") .build(); } } // store the snapshot copy of Metadata MetadataSnapshot snapshot = new MetadataSnapshot(); snapshot.getSnapshotKey().setCodeId(md.getCodeId()); snapshot.getSnapshotKey().setSnapshotStatus(md.getWorkflowStatus()); snapshot.setDoi(md.getDoi()); snapshot.setDoiIsMinted(md.getReleaseDate() != null); snapshot.setJson(md.toJson().toString()); em.merge(snapshot); // commit it em.getTransaction().commit(); // send NOTIFICATION if configured to do so sendStatusNotification(md); // we are done here return Response.ok().entity(mapper.createObjectNode().putPOJO("metadata", md.toJson()).toString()) .build(); } catch (BadRequestException e) { return e.getResponse(); } catch (NotFoundException e) { return ErrorResponse.notFound(e.getMessage()).build(); } catch (IllegalAccessException e) { log.warn("Persistence Error: Unable to update record, invalid owner: " + user.getEmail()); log.warn("Message: " + e.getMessage()); return ErrorResponse.forbidden("Logged in User is not allowed to modify this record.").build(); } catch (ValidationException e) { log.warn("Validation Error: " + e.getMessage()); return ErrorResponse.badRequest(e.getMessage()).build(); } catch (IOException | InvocationTargetException e) { if (em.getTransaction().isActive()) em.getTransaction().rollback(); log.warn("Persistence Error Submitting: " + e.getMessage()); return ErrorResponse.internalServerError("Persistence error submitting record.").build(); } finally { em.close(); } }
From source file:com.hiperf.common.ui.server.storage.impl.PersistenceHelper.java
private void processAddedManyToMany(ObjectsToPersist toPersist, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { Map<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> manyToManyAdded = toPersist .getManyToManyAddedByClassName(); if (manyToManyAdded != null && !manyToManyAdded.isEmpty()) { for (Entry<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>>> e : manyToManyAdded .entrySet()) {//from w ww.j a va 2 s .com String className = e.getKey(); Map<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> map = e .getValue(); if (map != null && !map.isEmpty()) { Class<?> clazz = Class.forName(className); for (Entry<com.hiperf.common.ui.shared.util.Id, Map<String, List<com.hiperf.common.ui.shared.util.Id>>> entry : map .entrySet()) { com.hiperf.common.ui.shared.util.Id id = entry.getKey(); Map<String, List<com.hiperf.common.ui.shared.util.Id>> m = entry.getValue(); if (m != null && !m.isEmpty()) { Object objId = id.getFieldValues().get(0); if (newIdByOldId.containsKey(objId)) objId = newIdByOldId.get(objId).getId(); Object o = em.find(clazz, objId); if (o != null) { PropertyDescriptor[] pds = propertyDescriptorsByClassName.get(className); for (Entry<String, List<com.hiperf.common.ui.shared.util.Id>> ee : m.entrySet()) { String attr = ee.getKey(); List<com.hiperf.common.ui.shared.util.Id> ll = ee.getValue(); if (ll != null && !ll.isEmpty()) { Collection coll = null; Class classInColl = null; PropertyDescriptor myPd = null; String mappedBy = null; for (PropertyDescriptor pd : pds) { if (pd.getName().equals(attr)) { myPd = pd; coll = (Collection) pd.getReadMethod().invoke(o, StorageService.emptyArg); if (coll == null) { if (List.class.isAssignableFrom(pd.getPropertyType())) coll = new ArrayList(); else coll = new HashSet(); pd.getWriteMethod().invoke(o, coll); } ManyToMany ann = pd.getReadMethod().getAnnotation(ManyToMany.class); if (ann == null) { ann = clazz.getDeclaredField(pd.getName()) .getAnnotation(ManyToMany.class); } if (ann != null) { mappedBy = ann.mappedBy(); } break; } } if (coll != null) { ParameterizedType genericType = (ParameterizedType) clazz .getDeclaredField(myPd.getName()).getGenericType(); if (genericType != null) { for (Type t : genericType.getActualTypeArguments()) { if (t instanceof Class && INakedObject.class.isAssignableFrom((Class) t)) { classInColl = (Class) t; break; } } } for (com.hiperf.common.ui.shared.util.Id i : ll) { Object idObj = i.getFieldValues().get(0); if (newIdByOldId.containsKey(idObj)) idObj = newIdByOldId.get(idObj).getId(); Object linkedObj = em.find(classInColl, idObj); if (mappedBy == null || mappedBy.length() == 0) coll.add(linkedObj); else { PropertyDescriptor[] pds2 = propertyDescriptorsByClassName .get(classInColl.getName()); if (pds2 == null) { pds2 = propertyDescriptorsByClassName .get(classInColl.getName()); } for (PropertyDescriptor pd : collectionsByClassName .get(classInColl.getName())) { if (pd.getName().equals(mappedBy)) { Collection coll2 = (Collection) pd.getReadMethod() .invoke(linkedObj, StorageService.emptyArg); if (coll2 == null) { if (List.class .isAssignableFrom(pd.getPropertyType())) coll2 = new ArrayList(); else coll2 = new HashSet(); pd.getWriteMethod().invoke(linkedObj, coll2); } coll2.add(o); } } em.merge(linkedObj); } if (linkedObj instanceof INakedObject) res.put(i, (INakedObject) linkedObj); } } } } res.put(id, (INakedObject) em.merge(o)); } } } } } } }
From source file:com.hiperf.common.ui.server.storage.impl.PersistenceHelper.java
private boolean doPersist(ObjectsToPersist toPersist, String userName, Map<com.hiperf.common.ui.shared.util.Id, INakedObject> res, Map<Object, IdHolder> newIdByOldId, EntityManager em, boolean validateBefore, Locale locale, boolean processExceptions) throws ClassNotFoundException, IntrospectionException, PersistenceException, IllegalAccessException, InvocationTargetException, InstantiationException { try {//from w ww . jav a2 s .com Validator validator = validatorFactory.getValidator(); List<INakedObject> toInsert = toPersist.getInsertedObjects(); if (toInsert != null) { int max = 100 * toInsert.size(); int idx = -1; int k = -1; int s = toInsert.size(); int prevSize = s; while (!toInsert.isEmpty()) { if (s == toInsert.size()) { k++; } else k = 0; if (k == 1) { logger.log(Level.FINE, "Impossible to persist data : one linked object not found in toInsert list"); return false; } if (prevSize == toInsert.size()) { idx++; } else { idx = 0; prevSize = toInsert.size(); } if (idx > max) { logger.log(Level.FINE, "Impossible to persist data : one linked object not found in toInsert list..."); return false; } Iterator<INakedObject> it = toInsert.iterator(); while (it.hasNext()) { INakedObject o = (INakedObject) it.next(); String className = o.getClass().getName(); if (o instanceof IAuditable) { IAuditable aud = (IAuditable) o; aud.setCreateUser(userName); aud.setCreateDate(new Date()); } Set<PropertyDescriptor> ids = idsByClassName.get(className); processLinkedCollectionsBeforePersist(o, collectionsByClassName.get(className)); if (!processLinkedObjectsBeforePersist(newIdByOldId, o, lazysByClassName.get(className), toPersist)) continue; if (!processLinkedObjectsBeforePersist(newIdByOldId, o, eagerObjectsByClassName.get(className), toPersist)) continue; if (generatedIdClasses.contains(className)) { PropertyDescriptor idPd = ids.iterator().next(); Object oldId = idPd.getReadMethod().invoke(o, StorageService.emptyArg); Object[] args = new Object[1]; if (!idPd.getPropertyType().isPrimitive()) args[0] = null; else args[0] = 0L; idPd.getWriteMethod().invoke(o, args); if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(o); if (errors != null && !errors.isEmpty()) { it.remove(); continue; } try { em.persist(o); } catch (Exception e) { it.remove(); continue; } } else em.persist(o); Object newId = idPd.getReadMethod().invoke(o, StorageService.emptyArg); newIdByOldId.put(oldId, new IdHolder(newId, className)); List<Object> idVals = new ArrayList<Object>(1); idVals.add(oldId); List<String> idFields = new ArrayList<String>(1); idFields.add(idPd.getName()); res.put(new com.hiperf.common.ui.shared.util.Id(idFields, idVals), o); it.remove(); } else { com.hiperf.common.ui.shared.util.Id id = getId(o, ids); int i = 0; boolean toProcess = true; for (Object idVal : id.getFieldValues()) { if ((idVal instanceof Long && ((Long) idVal).longValue() < 0) || (idVal instanceof String && ((String) idVal).startsWith(PersistenceManager.SEQ_PREFIX))) { IdHolder newIds = newIdByOldId.get(idVal); if (newIds != null) { String att = id.getFieldNames().get(i); for (PropertyDescriptor idPd : ids) { if (idPd.getName().equals(att)) { Object[] args = new Object[1]; args[0] = newIds.getId(); idPd.getWriteMethod().invoke(o, args); break; } } } else { toProcess = false; break; } } i++; } if (toProcess) { if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(o); if (errors != null && !errors.isEmpty()) { it.remove(); continue; } try { refreshManyToOneLinkedWithId(o, id, em); em.persist(o); } catch (Exception e) { it.remove(); continue; } } else { refreshManyToOneLinkedWithId(o, id, em); em.persist(o); } id = getId(o, ids); res.put(id, o); it.remove(); } } } } } Map<String, Set<com.hiperf.common.ui.shared.util.Id>> toDelete = toPersist .getRemovedObjectsIdsByClassName(); if (toDelete != null) { for (String className : toDelete.keySet()) { Set<com.hiperf.common.ui.shared.util.Id> ids = toDelete.get(className); Class<?> clazz = Class.forName(className); Map<Field, Field> toRemove = null; if (ids != null && !ids.isEmpty()) { com.hiperf.common.ui.shared.util.Id id = ids.iterator().next(); if (id.getFieldValues().size() > 1) { toRemove = new HashMap<Field, Field>(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (f.isAnnotationPresent(ManyToOne.class)) { Field[] ff = f.getType().getDeclaredFields(); for (Field lf : ff) { OneToMany ann = lf.getAnnotation(OneToMany.class); if (ann != null && ann.targetEntity() != null && ann.targetEntity().equals(clazz)) { toRemove.put(f, lf); } } } } // TODO : manage annotations on the getters... } } for (com.hiperf.common.ui.shared.util.Id id : ids) { INakedObject no = getObject(clazz, id, em); if (no != null) { if (toRemove != null && !toRemove.isEmpty()) { for (Entry<Field, Field> e : toRemove.entrySet()) { Field f = e.getKey(); Field ff = e.getValue(); boolean b1 = false; boolean b2 = false; if (!f.isAccessible()) { f.setAccessible(true); b1 = true; } if (!ff.isAccessible()) { ff.setAccessible(true); b2 = true; } ((Collection) ff.get(f.get(no))).remove(no); if (b1) f.setAccessible(false); if (b2) ff.setAccessible(false); } } else { // TODO : manage annotations on the getters... } em.remove(no); } } } } Map<String, Map<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>>> toUpdate = toPersist .getUpdatedObjects(); if (toUpdate != null) { for (String className : toUpdate.keySet()) { Map<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>> map = toUpdate .get(className); Class<?> clazz = Class.forName(className); Iterator<Entry<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>>> iterator = map .entrySet().iterator(); while (iterator.hasNext()) { Entry<com.hiperf.common.ui.shared.util.Id, Map<String, Serializable>> entry = iterator .next(); com.hiperf.common.ui.shared.util.Id id = entry.getKey(); INakedObject original = getObject(clazz, id, em); Map<String, Serializable> updateMap = entry.getValue(); for (String att : updateMap.keySet()) { Object object = updateMap.get(att); if (object != null && object instanceof NakedObjectHandler) { NakedObjectHandler oo = (NakedObjectHandler) object; com.hiperf.common.ui.shared.util.Id objId = oo.getId(); if (generatedIdClasses.contains(oo.getClassName()) && newIdByOldId.containsKey(objId.getFieldValues().get(0))) { IdHolder newIds = newIdByOldId.get(objId.getFieldValues().get(0)); List<Object> idVals = new ArrayList<Object>(1); idVals.add(newIds.getId()); List<String> idFields = new ArrayList<String>(1); idFields.add(idsByClassName.get(oo.getClassName()).iterator().next().getName()); com.hiperf.common.ui.shared.util.Id newObjId = new com.hiperf.common.ui.shared.util.Id( idFields, idVals); object = getObject(Class.forName(oo.getClassName()), newObjId, em); } else { object = getObject(Class.forName(oo.getClassName()), oo.getId(), em); } } updateAttributeValue(className, original, att, object); } if (original instanceof IAuditable) { IAuditable aud = (IAuditable) original; aud.setModifyUser(userName); aud.setModifyDate(new Date()); } INakedObject o = null; if (validateBefore) { Set<ConstraintViolation<INakedObject>> errors = validator.validate(original); if (errors != null && !errors.isEmpty()) { iterator.remove(); continue; } try { o = em.merge(original); em.flush(); } catch (Exception e) { iterator.remove(); continue; } } else o = em.merge(original); res.put(id, o); } } } processAddedManyToMany(toPersist, res, newIdByOldId, em); processRemovedManyToMany(toPersist, res, newIdByOldId, em); em.flush(); return true; } catch (Exception e) { logger.log(Level.WARNING, "Exception", e); if (processExceptions) { processDbExceptions(locale, e); return false; } else throw new PersistenceException(e); } }