Package org.apache.ojb.ejb.odmg

Source Code of org.apache.ojb.ejb.odmg.RollbackBean

package org.apache.ojb.ejb.odmg;

/* Copyright 2004-2005 The Apache Software Foundation
*
* 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.
*/


import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryByCriteria;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
import org.apache.ojb.ejb.ArticleVO;
import org.apache.ojb.ejb.PersonVO;
import org.apache.ojb.odmg.TransactionExt;
import org.odmg.OQLQuery;
import org.odmg.QueryException;

/**
* This is an session bean implementation used for testing different "rollback"
* scenarios for the ODMG implementation.
* <p/>
* <p/>
* <b>How to use ODMG</b> <br>
* <p/>
* To keep this example as simple as possible, we lookup a static OJB ODMG implementation instance
* on each bean instance.
* But it's recommended to bind an instance of the Implementation class in JNDI
* (at appServer start), open the database and lookup this instances via JNDI in
* ejbCreate().
* <br/>
* However the examples use a simple helper class to lookup the OJB resources.
* <p/>
* To use the odmg-api within your bean, you can do:
* <p/>
* <ol type="a">
* <li>
* Obtain the current Database from the Implementation instance - Attend<br>
* that there must be already a Database opened before.<br><i>
* db = odmg.getDatabase(null);<br>
* // ... do something<br>
* </i></li>
* <li>
* Obtain the current odmg-Transaction from the Implementation instance<br>
* to lock objects - Attend that there must be already a Database opened before.<br><i>
* Transaction tx = odmg.currentTransaction();<br>
* tx.lock(aObject, mode);
* </i></li>
* </ol>
* </p>
*
*
* @ejb:bean type="Stateless"
* name="RollbackBeanODMG"
* jndi-name="org.apache.ojb.ejb.odmg.RollbackBean"
* local-jndi-name="org.apache.ojb.ejb.odmg.RollbackBeanLocal"
* view-type="both"
* transaction-type="Container"
*
* @ejb:interface remote-class="org.apache.ojb.ejb.odmg.RollbackRemote"
* local-class="org.apache.ojb.ejb.odmg.RollbackLocal"
* extends="javax.ejb.EJBObject"
*
* @ejb:home remote-class="org.apache.ojb.ejb.odmg.RollbackHome"
* local-class="org.apache.ojb.ejb.odmg.RollbackLocalHome"
* extends="javax.ejb.EJBHome"
*
* @ejb:ejb-ref
*      ejb-name="PersonManagerODMGBean"
*      view-type="local"
*      ref-name="ejb/ojb/odmg/PersonManager"
*
* @ejb:ejb-ref
*      ejb-name="ArticleManagerODMGBean"
*      view-type="local"
*      ref-name="ejb/ojb/odmg/ArticleManager"
*
* @ejb:transaction type="Required"
*
* @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
* @version $Id: RollbackBean.java,v 1.1.2.4 2005/12/21 22:21:39 tomdz Exp $
*/
public class RollbackBean extends ODMGBaseBeanImpl implements SessionBean
{
    private Logger log = LoggerFactory.getLogger(RollbackBean.class);

    private static final String PERSON_MANAGER_EJB_REF_NAME = "java:comp/env/ejb/ojb/odmg/PersonManager";
    private static final String ARTICLE_MANAGER_EJB_REF_NAME = "java:comp/env/ejb/ojb/odmg/ArticleManager";

    private ArticleManagerODMGLocal am;
    private PersonManagerODMGLocal pm;

    public RollbackBean()
    {
    }

    /**
     * First stores all articles, persons form
     * the lists using ArticleManager and PersonManager
     * beans after doing that, a Exception will be thrown.
     *
     * @ejb:interface-method
     */
    public void rollbackOtherBeanUsing(List articles, List persons)
    {
        log.info("rollbackOtherBeanUsing method was called");
        //store all objects
        ArticleManagerODMGLocal am = getArticleManager();
        PersonManagerODMGLocal pm = getPersonManager();
        am.storeArticles(articles);
        pm.storePersons(persons);

        // after all is done we throw an exception to activate rollback process
        throw new EJBException("## Testing of rollback behaviour - rollbackOtherBeanUsing ##");
    }

    /**
     * First store a list of persons then we
     * store the article using a failure store
     * method in ArticleManager.
     *
     * @ejb:interface-method
     */
    public void rollbackOtherBeanUsing_2(ArticleVO article, List persons)
    {
        log.info("rollbackOtherBeanUsing_2 method was called");
        ArticleManagerODMGLocal am = getArticleManager();
        PersonManagerODMGLocal pm = getPersonManager();
        pm.storePersons(persons);
        am.failureStore(article);
    }

    /**
     * This test method expect an invalid object in the person list,
     * so that OJB cause an internal error.
     *
     * @ejb:interface-method
     */
    public void rollbackClientWrongInput(List articles, List persons)
    {
        log.info("rollbackClientWrongInput method was called");
        ArticleManagerODMGLocal am = getArticleManager();
        PersonManagerODMGLocal pm = getPersonManager();
        am.storeArticles(articles);
        pm.storePersons(persons);
    }

    /**
     * The bean will throw an exception before the method ends.
     *
     * @ejb:interface-method
     */
    public void rollbackThrowException(List objects)
    {
        log.info("rollbackThrowException method was called");
        storeObjects(objects);
        // now we throw an exception
        throw new EJBException("## Testing of rollback behaviour - rollbackThrowException ##");
    }

    /**
     * One of the objects passed by the client will cause an exception.
     *
     * @ejb:interface-method
     */
    public void rollbackPassInvalidObject(List objects)
    {
        log.info("rollbackPassInvalidObject method was called");
        storeObjects(objects);
    }

    /**
     * We do an odmg-tx.abort() call.
     *
     * @ejb:interface-method
     */
    public void rollbackOdmgAbort(List objects)
    {
        log.info("rollbackOdmgAbort method was called");
        storeObjects(objects);
        getImplementation().currentTransaction().abort();
    }

    /**
     * We do call ctx.setRollbackOnly and do odmg-tx.abort() call.
     *
     * @ejb:interface-method
     */
    public void rollbackSetRollbackOnly(List objects)
    {
        log.info("rollbackSetRollbackOnly method was called");
        storeObjects(objects);
        /*
        setRollbackOnly does only rollback the transaction, the client will not be
        notified by an RemoteException (tested on JBoss)
        */
        getSessionContext().setRollbackOnly();
        /*
        seems that some appServer expect that all used resources will be closed before
        the JTA-TXManager does call Synchronization#beforeCompletion(), so we have
        to cleanup used resources. This could be done by call abort on odmg-api
        */
        getImplementation().currentTransaction().abort();
    }

    /**
     * We do call ctx.setRollbackOnly and do odmg-tx.abort() call.
     *
     * @ejb:interface-method
     */
    public void rollbackSetRollbackAndThrowException(List objects)
    {
        log.info("rollbackSetRollbackAndThrowException method was called");
        storeObjects(objects);
        getSessionContext().setRollbackOnly();
        /*
        seems that some appServer expect that all used resources will be closed before
        the JTA-TXManager does call Synchronization#beforeCompletion(), so we have
        to cleanup used resources. This could be done by call abort on odmg-api
        */
        getImplementation().currentTransaction().abort();
        // to notify the client about the failure we throw an exception
        // if we don't throw such an exception the client don't get notified
        // about the failure
        throw new EJBException("## Testing of rollback behaviour - rollbackSetRollbackAndThrowException ##");
    }

    /**
     * We use several OJB services, start to iterate a query result and do
     * an odmg-tx.abort call.
     *
     * @ejb:interface-method
     */
    public void rollbackBreakIteration(List objectsToStore)
    {
        // now we mix up different api's and use PB-api too
        log.info("rollbackBreakIteration");
        /*
        store list of objects, then get these objects with Iterator, start
        iteration, then break
        */
        storeObjects(objectsToStore);
        TransactionExt tx = ((TransactionExt) getImplementation().currentTransaction());
        // force writing to DB
        tx.flush();
        Class searchClass = objectsToStore.get(0).getClass();
        PersistenceBroker broker = tx.getBroker();
        Query q = new QueryByCriteria(searchClass);
        // we get the iterator and step into the first found object
        Iterator it = broker.getIteratorByQuery(q);
        it.next();
        /*
        seems that some appServer expect that all used resources are closed before
        the JTA-TXManager does call Synchronization#beforeCompletion(), so we have
        to cleanup used resources. This could be done by call abort on odmg-api
        */
        getImplementation().currentTransaction().abort();
        // to notify the client about the failure we throw an exception
        // if we don't throw such an exception the client don't get notified
        // about the failure
        throw new EJBException("## Testing of rollback behaviour - rollbackBreakIteration ##");
    }

    /**
     * @ejb:interface-method
     */
    public List storeObjects(List objects)
    {
        return new ArrayList(super.storeObjects(objects));
    }

    /**
     * @ejb:interface-method
     */
    public void deleteObjects(List objects)
    {
        log.info("deleteObjects");
        super.deleteObjects(objects);
    }

    protected int getObjectCount(Class target)
    {
        log.info("getObjectCount was called");
        List list;
        try
        {
            OQLQuery query = getImplementation().newOQLQuery();
            query.create("select allObjects from " + target.getName());
            list = (List) query.execute();
            return list.size();
        }
        catch(QueryException e)
        {
            throw new EJBException("Query objects failed", e);
        }
    }

    /**
     * @ejb:interface-method
     */
    public int getArticleCount()
    {
        log.info("getArticleCount was called");
        return getObjectCount(ArticleVO.class);
    }

    /**
     * @ejb:interface-method
     */
    public int getPersonCount()
    {
        log.info("getPersonCount was called");
        return getObjectCount(PersonVO.class);
    }

    /**
     * @ejb:interface-method
     */
    public Collection getAllObjects(Class target)
    {
        if(log.isDebugEnabled()) log.debug("getAllObjects was called");
        OQLQuery query = getImplementation().newOQLQuery();
        try
        {
            query.create("select allObjects from " + target.getName());
            return (Collection) query.execute();
        }
        catch(Exception e)
        {
            log.error("OQLQuery failed", e);
            throw new OJBRuntimeException("OQLQuery failed", e);
        }
    }

    private ArticleManagerODMGLocal getArticleManager()
    {
        if (am == null)
        {
            Context context = null;
            try
            {
                context = new InitialContext();
                am = ((ArticleManagerODMGLocalHome) context.lookup(ARTICLE_MANAGER_EJB_REF_NAME)).create();
                log.info("** Found bean: " + am);
                return am;
            }
            catch (NamingException e)
            {
                log.error("Lookup using ejb-ref " + ARTICLE_MANAGER_EJB_REF_NAME + " failed", e);
                throw new EJBException(e);
            }
            catch (CreateException e)
            {
                log.error("Creation of ArticleManager failed", e);
                throw new EJBException(e);
            }
        }
        return am;
    }

    private PersonManagerODMGLocal getPersonManager()
    {
        if (pm == null)
        {
            Context context = null;
            try
            {
                context = new InitialContext();
                pm = ((PersonManagerODMGLocalHome) context.lookup(PERSON_MANAGER_EJB_REF_NAME)).create();
                log.info("** Found bean: " + pm);
                return pm;
            }
            catch (NamingException e)
            {
                log.error("Lookup using ejb-ref " + PERSON_MANAGER_EJB_REF_NAME + " failed", e);
                throw new EJBException(e);
            }
            catch (CreateException e)
            {
                log.error("Creation of PersonManager failed", e);
                throw new EJBException(e);
            }
        }
        return pm;
    }
}
TOP

Related Classes of org.apache.ojb.ejb.odmg.RollbackBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.