com.francetelecom.clara.cloud.commons.PersistenceTestUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.francetelecom.clara.cloud.commons.PersistenceTestUtil.java

Source

/**
 * Copyright (C) 2015 Orange
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.francetelecom.clara.cloud.commons;

import java.util.concurrent.Callable;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.commons.io.output.NullWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.francetelecom.clara.cloud.commons.xstream.XStreamUtils;
import com.thoughtworks.xstream.XStream;

/**
 * Utility to add persistence to tests that don't have some. This is designed so be instanciated by Junit tests that already have a persistence context declared
 * (None is provided as part of cloud-commons module test jar)
 */
public class PersistenceTestUtil {

    private static Logger logger = LoggerFactory.getLogger(PersistenceTestUtil.class.getName());

    @PersistenceContext
    EntityManager em;

    /**
     * Executes the given Runnable on the current thread within a new Transational context
     */
    @Transactional
    public void executeWithinTransaction(Runnable runnable) {
        runnable.run();
    }

    /**
     * Executes the given Calleable on the current thread within a new Transational context, and returns the computed result
     */
    @Transactional
    public <T> T executeWithinTransaction(Callable<T> calleable) throws Exception {
        return calleable.call();
    }

    @Transactional
    public void persistObjects(Object... objects) {
        for (Object object : objects) {
            persistObject(object, true);
        }
        em.flush();
    }

    @Transactional
    public void persistObject(Object object) {
        persistObject(object, false);
    }

    @Transactional
    public Object mergeObject(Object o) {
        return em.merge(o);
    }

    private void persistObject(Object object, boolean skipFlush) {
        // //First force its JSR 303 model validation to have meaningful exceptions if invalid
        ValidatorUtil.validate(object);

        // Then persist with JPA.
        try {
            em.persist(object);
            if (!skipFlush) {
                em.flush();
            }
        } catch (ConstraintViolationException e) {
            for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
                logger.error(constraintViolation.getRootBeanClass() + " " + constraintViolation.getPropertyPath()
                        + " " + constraintViolation.getMessage() + " " + constraintViolation.getRootBean()
                        + ", invalid value: [" + constraintViolation.getInvalidValue() + "]");
            }

            throw e;
        }
    }

    /**
     * Generic persistent eager loading of an object
     */
    @Transactional
    public <T> T reloadEntity(Class<T> classType, Object objectId, boolean forceEagerFetching) {
        T reloadedEntity = em.find(classType, objectId);
        if (reloadedEntity != null && forceEagerFetching) {
            forceEagerFetching(reloadedEntity);
        }
        return reloadedEntity;
    }

    private static void forceEagerFetching(Object entity) {
        XStream xStream = XStreamUtils.instanciateXstreamForHibernate();
        if (logger.isDebugEnabled()) {
            String xmlDump = xStream.toXML(entity);
            logger.debug("Xml dump:" + xmlDump);
        } else {
            // dump to equivalent of /dev/null
            xStream.toXML(entity, NullWriter.NULL_WRITER);
        }
    }

}