Example usage for javax.ejb TransactionAttributeType REQUIRED

List of usage examples for javax.ejb TransactionAttributeType REQUIRED

Introduction

In this page you can find the example usage for javax.ejb TransactionAttributeType REQUIRED.

Prototype

TransactionAttributeType REQUIRED

To view the source code for javax.ejb TransactionAttributeType REQUIRED.

Click Source Link

Document

If a client invokes the enterprise bean's method while the client is associated with a transaction context, the container invokes the enterprise bean's method in the client's transaction context.

Usage

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}/*from   w w  w.  j  a va2  s.c o  m*/
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public long save(FxGroupEdit group) throws FxApplicationException {
    FxPermissionUtils.checkRole(FxContext.getUserTicket(), Role.StructureManagement);
    long returnId = group.getId();
    boolean reload;
    Connection con = null;
    try {
        con = Database.getDbConnection();
        reload = updateGroup(con, group);
        if (reload)
            StructureLoader.reload(con);
    } catch (SQLException e) {
        EJBUtils.rollback(ctx);
        throw new FxCreateException(LOG, e, "ex.db.sqlError", e.getMessage());
    } catch (FxCacheException e) {
        EJBUtils.rollback(ctx);
        throw new FxCreateException(e, "ex.cache", e.getMessage());
    } catch (FxLoadException e) {
        EJBUtils.rollback(ctx);
        throw new FxCreateException(e);
    } finally {
        Database.closeObjects(AssignmentEngineBean.class, con, null);
    }
    return returnId;
}

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}/*from   w  w w .  j a  va  2s . c  o  m*/
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public long getPropertyInstanceCount(long propertyId) throws FxDbException {
    Connection con = null;
    PreparedStatement ps = null;
    long count = 0;
    try {
        con = Database.getDbConnection();
        ps = con.prepareStatement("SELECT COUNT(*) FROM " + TBL_CONTENT_DATA + " WHERE TPROP=?");
        ps.setLong(1, propertyId);
        ResultSet rs = ps.executeQuery();
        rs.next();
        count = rs.getLong(1);
        ps.close();
        if (EJBLookup.getDivisionConfigurationEngine().isFlatStorageEnabled()) {
            //also examine flat storage entries
            count += FxFlatStorageManager.getInstance().getPropertyInstanceCount(con, propertyId);
        }
    } catch (SQLException e) {
        throw new FxDbException(LOG, e, "ex.db.sqlError", e.getMessage());
    } finally {
        Database.closeObjects(AssignmentEngineBean.class, con, ps);
    }
    return count;
}

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}/* ww w. j a va2 s  .  c o  m*/
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public long getAssignmentInstanceCount(long assignmentId) throws FxApplicationException {
    Connection con = null;
    PreparedStatement ps = null;
    long count = 0;
    try {
        con = Database.getDbConnection();
        ps = con.prepareStatement("SELECT COUNT(*) FROM " + TBL_CONTENT_DATA + " WHERE ASSIGN=?");
        ps.setLong(1, assignmentId);
        ResultSet rs = ps.executeQuery();
        rs.next();
        count = rs.getLong(1);
        ps.close();
        if (EJBLookup.getDivisionConfigurationEngine().isFlatStorageEnabled()) {
            //also examine flat storage entries
            count += FxFlatStorageManager.getInstance().getAssignmentInstanceCount(con, assignmentId);
        }
    } catch (SQLException e) {
        throw new FxDbException(LOG, e, "ex.db.sqlError", e.getMessage());
    } finally {
        Database.closeObjects(AssignmentEngineBean.class, con, ps);
    }
    return count;
}

From source file:fr.ortolang.diffusion.core.CoreServiceBean.java

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public MetadataObject createMetadataObject(String workspace, String path, String name, String hash,
        String filename, boolean purgeChildren)
        throws CoreServiceException, KeyNotFoundException, InvalidPathException, AccessDeniedException,
        MetadataFormatException, PathNotFoundException, WorkspaceReadOnlyException, KeyAlreadyExistsException {
    String key = UUID.randomUUID().toString();
    try {/*  w w w  .j a  va2  s.c o  m*/
        return createMetadataObject(workspace, key, path, name, hash, filename, purgeChildren);
    } catch (KeyAlreadyExistsException e) {
        ctx.setRollbackOnly();
        LOGGER.log(Level.WARNING, "the generated key already exists : " + key);
        throw e;
    }
}

From source file:fr.ortolang.diffusion.core.CoreServiceBean.java

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public MetadataObject createMetadataObject(String wskey, String key, String path, String name, String hash,
        String filename, boolean purgeChildren) throws CoreServiceException, KeyAlreadyExistsException,
        InvalidPathException, MetadataFormatException, PathNotFoundException, WorkspaceReadOnlyException {
    LOGGER.log(Level.FINE, "create metadataobject with key [" + key + "] into workspace [" + wskey
            + "] for path [" + path + "] with name [" + name + "]");
    try {//from   w ww  .  j  ava  2 s  .  com
        PathBuilder npath = PathBuilder.fromPath(path);
        PathBuilder ppath = npath.clone().parent();

        String caller = membership.getProfileKeyForConnectedIdentifier();
        List<String> subjects = membership.getConnectedIdentifierSubjects();
        authorisation.checkAuthentified(subjects);
        LOGGER.log(Level.FINEST, "user [" + caller + "] is authentified");

        OrtolangObjectIdentifier wsidentifier = registry.lookup(wskey);
        checkObjectType(wsidentifier, Workspace.OBJECT_TYPE);
        LOGGER.log(Level.FINEST, "workspace with key [" + wskey + "] exists");

        Workspace ws = em.find(Workspace.class, wsidentifier.getId());
        if (ws == null) {
            throw new CoreServiceException(
                    "unable to load workspace with id [" + wsidentifier.getId() + "] from storage");
        }
        if (applyReadOnly(caller, subjects, ws)) {
            throw new WorkspaceReadOnlyException("unable to create metadata object in workspace with key ["
                    + wskey + "] because it is read only");
        }
        ws.setKey(wskey);
        LOGGER.log(Level.FINEST, "workspace loaded");

        authorisation.checkPermission(ws.getHead(), subjects, "create");
        LOGGER.log(Level.FINEST,
                "user [" + caller + "] has 'create' permission on the head collection of this workspace");

        String tkey;
        Collection parent = null;
        CollectionElement element = null;
        if (npath.isRoot()) {
            tkey = ws.getHead();
        } else {
            parent = loadCollectionAtPath(ws.getHead(), ppath, ws.getClock());
            LOGGER.log(Level.FINEST, "parent collection loaded for path " + ppath.build());
            element = parent.findElementByName(npath.part());
            if (element == null) {
                throw new PathNotFoundException(npath.build());
            }
            LOGGER.log(Level.FINEST, "collection element found for name " + npath.part());
            tkey = element.getKey();
        }

        OrtolangObjectIdentifier tidentifier = registry.lookup(tkey);
        if (!tidentifier.getType().equals(Link.OBJECT_TYPE)
                && !tidentifier.getType().equals(Collection.OBJECT_TYPE)
                && !tidentifier.getType().equals(DataObject.OBJECT_TYPE)) {
            throw new CoreServiceException("metadata target can only be a Link, a DataObject or a Collection.");
        }

        MetadataObject meta = new MetadataObject();
        meta.setId(UUID.randomUUID().toString());
        meta.setName(name);

        MetadataFormat format = getMetadataFormat(name);
        if (format == null) {
            LOGGER.log(Level.SEVERE, "Unable to find a metadata format for name: " + name);
            throw new CoreServiceException("unknown metadata format for name: " + name);
        }

        if (hash != null && hash.length() > 0) {
            if (format.isValidationNeeded()) {
                validateMetadata(hash, format);
            }
            meta.setSize(binarystore.size(hash));
            if (filename != null) {
                meta.setContentType(binarystore.type(hash, filename));
            } else {
                meta.setContentType(binarystore.type(hash));
            }
            meta.setStream(hash);
        } else {
            meta.setSize(0);
            meta.setContentType("application/octet-stream");
            meta.setStream("");
        }

        meta.setFormat(format.getId());
        meta.setTarget(tkey);
        meta.setKey(key);
        em.persist(meta);

        Properties properties = new Properties();
        properties.put(WORKSPACE_REGISTRY_PROPERTY_KEY, wskey);
        registry.register(key, meta.getObjectIdentifier(), caller, properties);

        authorisation.clonePolicy(key, ws.getHead());

        switch (tidentifier.getType()) {
        case Collection.OBJECT_TYPE:
            Collection collection = em.find(Collection.class, tidentifier.getId());
            if (collection == null) {
                ctx.setRollbackOnly();
                throw new CoreServiceException(
                        "unable to load collection with id [" + tidentifier.getId() + "] from storage");
            }
            collection.setKey(tkey);
            for (MetadataElement mde : collection.getMetadatas()) {
                if (mde.getName().equals(name)) {
                    ctx.setRollbackOnly();
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] already exists for collection at path [" + npath.build() + "]");
                }
            }
            if (collection.getClock() < ws.getClock()) {
                Collection clone = cloneCollection(ws.getHead(), collection, ws.getClock());
                tkey = clone.getKey();
                meta.setTarget(tkey);
                if (parent != null) {
                    parent.removeElement(element);
                    parent.addElement(new CollectionElement(Collection.OBJECT_TYPE, clone.getName(),
                            System.currentTimeMillis(), 0, Collection.MIME_TYPE, clone.getKey()));
                    em.merge(parent);
                    registry.update(parent.getKey());
                }
                collection = clone;
            }
            collection.addMetadata(new MetadataElement(name, key));
            em.merge(collection);
            if (purgeChildren) {
                LOGGER.log(Level.FINE, "Purging children metadata");
                purgeChildrenMetadata(collection, wskey, path, name);
            }
            break;
        case DataObject.OBJECT_TYPE:
            DataObject object = em.find(DataObject.class, tidentifier.getId());
            if (object == null) {
                ctx.setRollbackOnly();
                throw new CoreServiceException(
                        "unable to load object with id [" + tidentifier.getId() + "] from storage");
            }
            object.setKey(tkey);
            for (MetadataElement mde : object.getMetadatas()) {
                if (mde.getName().equals(name)) {
                    ctx.setRollbackOnly();
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] already exists for object at path [" + npath.build() + "]");
                }
            }
            if (object.getClock() < ws.getClock()) {
                DataObject clone = cloneDataObject(ws.getHead(), object, ws.getClock());
                tkey = clone.getKey();
                meta.setTarget(tkey);
                if (parent == null) {
                    throw new CoreServiceException("An object should have a parent");
                }
                parent.removeElement(element);
                parent.addElement(new CollectionElement(DataObject.OBJECT_TYPE, clone.getName(),
                        System.currentTimeMillis(), clone.getSize(), clone.getMimeType(), clone.getKey()));
                em.merge(parent);
                registry.update(parent.getKey());
                object = clone;
            }
            object.addMetadata(new MetadataElement(name, key));
            em.merge(object);
            break;
        case Link.OBJECT_TYPE:
            Link link = em.find(Link.class, tidentifier.getId());
            if (link == null) {
                ctx.setRollbackOnly();
                throw new CoreServiceException(
                        "unable to load link with id [" + tidentifier.getId() + "] from storage");
            }
            link.setKey(tkey);
            for (MetadataElement mde : link.getMetadatas()) {
                if (mde.getName().equals(name)) {
                    ctx.setRollbackOnly();
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] already exists for link at path [" + npath.build() + "]");
                }
            }
            if (link.getClock() < ws.getClock()) {
                Link clone = cloneLink(ws.getHead(), link, ws.getClock());
                tkey = clone.getKey();
                meta.setTarget(tkey);
                if (parent == null) {
                    throw new CoreServiceException("A link should have a parent");
                }
                parent.removeElement(element);
                parent.addElement(new CollectionElement(Link.OBJECT_TYPE, clone.getName(),
                        System.currentTimeMillis(), 0, Link.MIME_TYPE, clone.getKey()));
                em.merge(parent);
                registry.update(parent.getKey());
                link = clone;
            }
            link.addMetadata(new MetadataElement(name, key));
            em.merge(link);
            break;
        }
        em.merge(meta);

        indexing.index(tkey);

        ws.setChanged(true);
        em.merge(ws);
        registry.update(ws.getKey());
        LOGGER.log(Level.FINEST, "workspace set changed");

        ArgumentsBuilder argsBuilder = new ArgumentsBuilder(5).addArgument("ws-alias", ws.getAlias())
                .addArgument("key", key).addArgument("tkey", tkey).addArgument("path", npath.build())
                .addArgument("name", name);
        notification.throwEvent(wskey, caller, Workspace.OBJECT_TYPE,
                OrtolangEvent.buildEventType(CoreService.SERVICE_NAME, MetadataObject.OBJECT_TYPE, "create"),
                argsBuilder.build());

        return meta;
    } catch (KeyLockedException | KeyNotFoundException | RegistryServiceException | NotificationServiceException
            | IdentifierAlreadyRegisteredException | AuthorisationServiceException | MembershipServiceException
            | BinaryStoreServiceException | DataNotFoundException | CloneException | IndexingServiceException
            | OrtolangException e) {
        ctx.setRollbackOnly();
        LOGGER.log(Level.SEVERE, "unexpected error occurred during metadata creation", e);
        throw new CoreServiceException(
                "unable to create metadata into workspace [" + wskey + "] for path [" + path + "]", e);
    }
}

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}/*from   www .  ja va2 s.co  m*/
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void flattenAssignment(FxPropertyAssignment assignment) throws FxApplicationException {
    flattenAssignment(FxFlatStorageManager.getInstance().getDefaultStorage(), assignment);
}

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}//from   www. ja  va2s . c o m
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void flattenAssignment(String storage, FxPropertyAssignment assignment) throws FxApplicationException {
    Connection con = null;
    try {
        con = Database.getDbConnection();
        final FxFlatStorage fs = FxFlatStorageManager.getInstance();
        fs.flatten(con, storage, assignment);

        StructureLoader.reload(con);
    } catch (FxApplicationException e) {
        EJBUtils.rollback(ctx);
        throw e;
    } catch (SQLException e) {
        EJBUtils.rollback(ctx);
        throw new FxDbException(e);
    } catch (FxCacheException e) {
        EJBUtils.rollback(ctx);
        throw new FxUpdateException(e);
    } finally {
        Database.closeObjects(AssignmentEngineBean.class, con, null);
    }
}

From source file:com.flexive.ejb.beans.structure.AssignmentEngineBean.java

/**
 * {@inheritDoc}// w ww  .ja va  2s. c o  m
 */
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void unflattenAssignment(FxPropertyAssignment assignment) throws FxApplicationException {
    Connection con = null;
    try {
        con = Database.getDbConnection();

        FxFlatStorageManager.getInstance().unflatten(con, assignment);

        StructureLoader.reload(con);
    } catch (FxApplicationException e) {
        EJBUtils.rollback(ctx);
        throw e;
    } catch (FxCacheException e) {
        EJBUtils.rollback(ctx);
        throw new FxUpdateException(e);
    } catch (SQLException e) {
        EJBUtils.rollback(ctx);
        throw new FxDbException(e);
    } finally {
        Database.closeObjects(AssignmentEngineBean.class, con, null);
    }
}

From source file:fr.ortolang.diffusion.core.CoreServiceBean.java

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public MetadataObject updateMetadataObject(String wskey, String path, String name, String hash, String filename,
        boolean purgeChildren) throws CoreServiceException, KeyNotFoundException, InvalidPathException,
        AccessDeniedException, MetadataFormatException, PathNotFoundException, WorkspaceReadOnlyException {
    return updateMetadataObject(wskey, path, name, hash, filename, purgeChildren, null);
}

From source file:fr.ortolang.diffusion.core.CoreServiceBean.java

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public MetadataObject updateMetadataObject(String wskey, String path, String name, String hash, String filename,
        boolean purgeChildren, String format) throws CoreServiceException, InvalidPathException,
        MetadataFormatException, PathNotFoundException, WorkspaceReadOnlyException {
    LOGGER.log(Level.FINE, "updating metadata content into workspace [" + wskey + "] for path [" + path
            + "] and name [" + name + "]");
    try {/*w w w.java 2 s. c o m*/
        PathBuilder npath = PathBuilder.fromPath(path);
        PathBuilder ppath = npath.clone().parent();

        String caller = membership.getProfileKeyForConnectedIdentifier();
        List<String> subjects = membership.getConnectedIdentifierSubjects();
        authorisation.checkAuthentified(subjects);
        LOGGER.log(Level.FINEST, "user [" + caller + "] is authentified");

        OrtolangObjectIdentifier wsidentifier = registry.lookup(wskey);
        checkObjectType(wsidentifier, Workspace.OBJECT_TYPE);
        LOGGER.log(Level.FINEST, "workspace with key [" + wskey + "] exists");

        Workspace ws = em.find(Workspace.class, wsidentifier.getId());
        if (ws == null) {
            throw new CoreServiceException(
                    "unable to load workspace with id [" + wsidentifier.getId() + "] from storage");
        }
        if (applyReadOnly(caller, subjects, ws)) {
            throw new WorkspaceReadOnlyException("unable to update metadata object in workspace with key ["
                    + wskey + "] because it is read only");
        }
        ws.setKey(wskey);
        LOGGER.log(Level.FINEST, "workspace loaded");

        authorisation.checkPermission(ws.getHead(), subjects, "update");
        LOGGER.log(Level.FINEST,
                "user [" + caller + "] has 'update' permission on the head collection of this workspace");

        String current = resolveWorkspacePath(wskey, Workspace.HEAD, npath.build());
        OrtolangObjectIdentifier ctidentifier = registry.lookup(current);
        if (!ctidentifier.getType().equals(Link.OBJECT_TYPE)
                && !ctidentifier.getType().equals(Collection.OBJECT_TYPE)
                && !ctidentifier.getType().equals(DataObject.OBJECT_TYPE)) {
            throw new CoreServiceException("metadata target can only be a Link, a DataObject or a Collection.");
        }
        MetadataElement cmdelement = null;
        switch (ctidentifier.getType()) {
        case Collection.OBJECT_TYPE:
            Collection collection = em.find(Collection.class, ctidentifier.getId());
            if (collection == null) {
                throw new CoreServiceException(
                        "unable to load collection with id [" + ctidentifier.getId() + "] from storage");
            }
            if (collection.findMetadataByName(name) == null) {
                throw new CoreServiceException("a metadata object with name [" + name
                        + "] does not exists for collection at path [" + npath.build() + "]");
            }
            cmdelement = collection.findMetadataByName(name);
            break;
        case DataObject.OBJECT_TYPE:
            DataObject object = em.find(DataObject.class, ctidentifier.getId());
            if (object == null) {
                throw new CoreServiceException(
                        "unable to load object with id [" + ctidentifier.getId() + "] from storage");
            }
            if (object.findMetadataByName(name) == null) {
                throw new CoreServiceException("a metadata object with name [" + name
                        + "] does not exists for object at path [" + npath.build() + "]");
            }
            cmdelement = object.findMetadataByName(name);
            break;
        case Link.OBJECT_TYPE:
            Link link = em.find(Link.class, ctidentifier.getId());
            if (link == null) {
                throw new CoreServiceException(
                        "unable to load link with id [" + ctidentifier.getId() + "] from storage");
            }
            if (link.findMetadataByName(name) == null) {
                throw new CoreServiceException("a metadata object with name [" + name
                        + "] does not exists for link at path [" + npath.build() + "]");
            }
            cmdelement = link.findMetadataByName(name);
            break;
        }
        if (cmdelement == null) {
            throw new CoreServiceException("unable to find current metadata target into workspace [" + wskey
                    + "] for path [" + npath.build() + "] and name [" + name + "]");
        }
        OrtolangObjectIdentifier cidentifier = registry.lookup(cmdelement.getKey());
        checkObjectType(cidentifier, MetadataObject.OBJECT_TYPE);
        MetadataObject cmeta = em.find(MetadataObject.class, cidentifier.getId());
        if (cmeta == null) {
            throw new CoreServiceException(
                    "unable to load metadata with id [" + cidentifier.getId() + "] from storage");
        }
        if (!cmeta.getStream().equals(hash)) {
            String tkey = ws.getHead();
            Collection parent = null;
            CollectionElement element = null;
            if (!npath.isRoot()) {
                parent = loadCollectionAtPath(ws.getHead(), ppath, ws.getClock());
                LOGGER.log(Level.FINEST, "parent collection loaded for path " + ppath.build());
                element = parent.findElementByName(npath.part());
                if (element == null) {
                    throw new PathNotFoundException(npath.build());
                }
                LOGGER.log(Level.FINEST, "collection element found for name " + npath.part());
                tkey = element.getKey();
            }

            OrtolangObjectIdentifier tidentifier = registry.lookup(tkey);
            if (!tidentifier.getType().equals(Link.OBJECT_TYPE)
                    && !tidentifier.getType().equals(Collection.OBJECT_TYPE)
                    && !tidentifier.getType().equals(DataObject.OBJECT_TYPE)) {
                throw new CoreServiceException(
                        "metadata target can only be a Link, a DataObject or a Collection.");
            }

            MetadataElement mdelement = null;
            Collection collection = null;
            switch (tidentifier.getType()) {
            case Collection.OBJECT_TYPE:
                collection = em.find(Collection.class, tidentifier.getId());
                if (collection == null) {
                    throw new CoreServiceException(
                            "unable to load collection with id [" + tidentifier.getId() + "] from storage");
                }
                collection.setKey(tkey);
                if (collection.findMetadataByName(name) == null) {
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] does not exists for collection at path [" + npath.build() + "]");
                }
                if (collection.getClock() < ws.getClock()) {
                    Collection clone = cloneCollection(ws.getHead(), collection, ws.getClock());
                    tkey = clone.getKey();
                    if (parent != null) {
                        parent.removeElement(element);
                        parent.addElement(new CollectionElement(Collection.OBJECT_TYPE, clone.getName(),
                                System.currentTimeMillis(), 0, Collection.MIME_TYPE, clone.getKey()));
                    }
                    collection = clone;
                }
                mdelement = collection.findMetadataByName(name);
                break;
            case DataObject.OBJECT_TYPE:
                DataObject object = em.find(DataObject.class, tidentifier.getId());
                if (object == null) {
                    throw new CoreServiceException(
                            "unable to load object with id [" + tidentifier.getId() + "] from storage");
                }
                object.setKey(tkey);
                if (object.findMetadataByName(name) == null) {
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] does not exists for object at path [" + npath.build() + "]");
                }
                if (object.getClock() < ws.getClock()) {
                    DataObject clone = cloneDataObject(ws.getHead(), object, ws.getClock());
                    tkey = clone.getKey();
                    if (parent == null) {
                        throw new CoreServiceException("An object should have a parent");
                    }
                    parent.removeElement(element);
                    parent.addElement(new CollectionElement(DataObject.OBJECT_TYPE, clone.getName(),
                            System.currentTimeMillis(), clone.getSize(), clone.getMimeType(), clone.getKey()));
                    object = clone;
                }
                mdelement = object.findMetadataByName(name);
                break;
            case Link.OBJECT_TYPE:
                Link link = em.find(Link.class, tidentifier.getId());
                if (link == null) {
                    throw new CoreServiceException(
                            "unable to load link with id [" + tidentifier.getId() + "] from storage");
                }
                link.setKey(tkey);
                if (link.findMetadataByName(name) == null) {
                    throw new CoreServiceException("a metadata object with name [" + name
                            + "] does not exists for link at path [" + npath.build() + "]");
                }
                if (link.getClock() < ws.getClock()) {
                    Link clone = cloneLink(ws.getHead(), link, ws.getClock());
                    tkey = clone.getKey();
                    if (parent == null) {
                        throw new CoreServiceException("A link should have a parent");
                    }
                    parent.removeElement(element);
                    parent.addElement(new CollectionElement(Link.OBJECT_TYPE, clone.getName(),
                            System.currentTimeMillis(), 0, Link.MIME_TYPE, clone.getKey()));
                    link = clone;
                }
                mdelement = link.findMetadataByName(name);
                break;
            }

            if (mdelement == null) {
                throw new CoreServiceException("unable to find metadata object into workspace [" + wskey
                        + "] for path [" + npath.build() + "] and name [" + name + "]");
            }
            OrtolangObjectIdentifier identifier = registry.lookup(mdelement.getKey());
            checkObjectType(identifier, MetadataObject.OBJECT_TYPE);
            MetadataObject meta = em.find(MetadataObject.class, identifier.getId());
            if (meta == null) {
                throw new CoreServiceException(
                        "unable to load metadata with id [" + identifier.getId() + "] from storage");
            }
            meta.setKey(mdelement.getKey());

            if (hash != null && hash.length() > 0) {
                if (filename != null) {
                    meta.setContentType(binarystore.type(hash, filename));
                } else {
                    meta.setContentType(binarystore.type(hash));
                }

                if (format != null) {
                    meta.setFormat(format);
                }
                MetadataFormat metadataFormat = findMetadataFormatById(meta.getFormat());
                if (metadataFormat == null) {
                    LOGGER.log(Level.SEVERE, "Unable to find a metadata format for name: " + name);
                    throw new CoreServiceException("unknown metadata format for name: " + name);
                }
                if (metadataFormat.isValidationNeeded()) {
                    validateMetadata(hash, metadataFormat);
                }
                meta.setSize(binarystore.size(hash));
                meta.setStream(hash);
                meta.setTarget(tkey);
            } else {
                throw new CoreServiceException(
                        "unable to update a metadata with an empty content (hash is null)");
            }
            em.merge(meta);

            registry.update(mdelement.getKey());
            indexing.index(tkey);

            if (collection != null && purgeChildren) {
                LOGGER.log(Level.FINE, "Purging children metadata");
                purgeChildrenMetadata(collection, wskey, path, name);
            }

            ws.setChanged(true);
            em.merge(ws);
            registry.update(ws.getKey());
            LOGGER.log(Level.FINEST, "workspace set changed");

            ArgumentsBuilder argsBuilder = new ArgumentsBuilder(5).addArgument("ws-alias", ws.getAlias())
                    .addArgument("key", mdelement.getKey()).addArgument("tkey", tkey)
                    .addArgument("path", npath.build()).addArgument("name", name);
            notification.throwEvent(wskey, caller, Workspace.OBJECT_TYPE, OrtolangEvent.buildEventType(
                    CoreService.SERVICE_NAME, MetadataObject.OBJECT_TYPE, "update"), argsBuilder.build());

            return meta;
        } else {
            LOGGER.log(Level.FINEST, "no changes detected with current metadata object, nothing to do");
            return cmeta;
        }
    } catch (KeyLockedException | KeyNotFoundException | RegistryServiceException | NotificationServiceException
            | AuthorisationServiceException | MembershipServiceException | BinaryStoreServiceException
            | DataNotFoundException | CloneException | IndexingServiceException | OrtolangException e) {
        ctx.setRollbackOnly();
        LOGGER.log(Level.SEVERE, "unexpected error occurred during metadata creation", e);
        throw new CoreServiceException("unable to create metadata into workspace [" + wskey + "] for path ["
                + path + "] and name [" + name + "]", e);
    }
}