Example usage for javax.persistence EntityManager merge

List of usage examples for javax.persistence EntityManager merge

Introduction

In this page you can find the example usage for javax.persistence EntityManager merge.

Prototype

public <T> T merge(T entity);

Source Link

Document

Merge the state of the given entity into the current persistence context.

Usage

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);
    }

}