## ---------------------------------------------------------------------------
## JOnAS: Java(TM) Open Application Server
## Copyright (C) 1999-2004 Bull S.A.
## Contact: jonas-team@objectweb.org
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
## USA
##
## ---------------------------------------------------------------------------
## $Id: JEntityCmp2.vm 12763 2008-01-31 12:35:16Z durieuxp $
## ---------------------------------------------------------------------------

//
// This class is the bean specific part of the container managed persistence with JDBC.
// Generated by JOnAS's GenIC tool via Velocity.
// DO NOT EDIT THIS FILE.

#set( $IsAutomaticPk = $dd.isAutomaticPk() )
#set( $IsUndefinedPK = $dd.isUndefinedPK() )
package $package;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;

import javax.ejb.CreateException;
import javax.ejb.DuplicateKeyException;
import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.RemoveException;

import org.objectweb.util.monolog.api.BasicLevel;

import org.objectweb.jorm.api.PAccessor;
import org.objectweb.jorm.api.PBinding;
import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PExceptionExistingDSI;
import org.objectweb.jorm.api.PExceptionIO;
import org.objectweb.jorm.naming.api.PExceptionNaming;
import org.objectweb.jorm.naming.api.PBinder;
import org.objectweb.jorm.naming.api.PExceptionExistingName;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.jorm.naming.api.PNameCoder;
import org.objectweb.jorm.naming.api.PNameGetter;
import org.objectweb.jorm.naming.api.PNamingContext;
import org.objectweb.jorm.type.api.PType;
import org.objectweb.jorm.type.api.PTypeSpace;

import org.ow2.jonas.lib.ejb21.jorm.Coder;
import org.ow2.jonas.lib.ejb21.jorm.GenClassElement;
import org.ow2.jonas.lib.ejb21.jorm.GenClassListener;
import org.ow2.jonas.lib.ejb21.jorm.MedorFactory;
import org.ow2.jonas.lib.ejb21.jorm.PObject;
import org.ow2.jonas.lib.ejb21.jorm.PObjectHome;
import org.ow2.jonas.lib.ejb21.JEntityContext;
import org.ow2.jonas.lib.ejb21.JEntitySwitch;
import org.ow2.jonas.lib.ejb21.JEntityFactory;
import org.ow2.jonas.lib.ejb21.TraceEjb;
import org.ow2.jonas.lib.ejb21.MarshallTool;
import org.ow2.jonas.lib.ejb21.JavaType;
import org.ow2.jonas.lib.ejb21.ExceptionHelper;

import org.objectweb.medor.api.MedorException;
import org.objectweb.medor.api.TupleStructure;
import org.objectweb.medor.expression.api.ParameterOperand;
import org.objectweb.medor.expression.lib.BasicParameterOperand;
import org.objectweb.medor.tuple.api.Tuple;
import org.objectweb.medor.tuple.api.TupleCollection;
import org.objectweb.medor.type.lib.PTypeSpaceMedor;

public class $class extends ${dd.getJormStateClassName()} implements PAccessor,
                                             ${dd.getJormAccessorClassName()}
#if($pkIsUserClass)
    ,${dd.getJormPNameGetterClassName()}
#end
{

###################################
############## Fields #############
###################################
#foreach ($F in $fieldList)
//    private ${F.getTypeName()} ${F.getName()};

#end
#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
    private ${F.getGenClassName()} ${F.getName()} = null;
    private boolean ${F.getName()}loaded = false;
#*  *##else
    private ${F.getTypeName()} ${F.getName()} = null;
#*  *##end
//    private PName ${F.getName()}PName = null;

#end
    protected JEntityContext ejbContext = null;
    private MedorFactory factory = null;
    private boolean setPkAllowed = false;
    private boolean selectForUpdate = false;

    public PNameGetter encode(String field, PName pname)
        throws PExceptionNaming {
        PNameCoder coder = factory.getPNameCoder(field);
        if (pname == null) {
            pname = coder.getNull();
        }
        PNameGetter result = (PNameGetter) coder.encodeAbstract(pname);
        return result;
    }

    public PName decode(String field, PNameGetter png, Object ctx)
        throws PExceptionNaming {
        PNameCoder coder = factory.getPNameCoder(field);
        if (png == null) {
            return coder.getNull();
        } else {
            return coder.decodeAbstract(png, ctx);
        }
    }

########################################################################
############ Accessors (EJB 2.0 & Jorm) for the CMP fields #############
########################################################################
#foreach ($F in $fieldList)
    //-------------------------------------------------------------//
    //------------------- Field  ${F.getName()}
    //-------------------------------------------------------------//
    // EJB 2.0 Getter
    public ${F.getTypeName()} ${F.getGetterName()}() {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "return " + ${F.jormGetter()}());
#*   *##if (!$F.isMustBeConvert())
        return (${F.getTypeName()}) ${F.jormGetter()}();
#*   *##else
        return (${F.getTypeName()}) ${F.getConvertClassName()}.toMemory(${F.jormGetter()}());
#*   *##end
    }

    // EJB 2.0 Setter
    public void ${F.getSetterName()}(${F.getTypeName()} val) {
        //TraceEjb.interp.log(BasicLevel.DEBUG,"param=" + val);
#*   *##if ($F.isPrimaryKey())
#set( $pkField = ${F.jormSetter()} )
        if (!setPkAllowed) {
            throw new IllegalStateException("Must not reset a primary key value(${F.jormGetter()}() field)");
        }
#*   *##end
        ejbContext.setDirty(true);
#*   *##if (!$F.isMustBeConvert())
        this.${F.jormSetter()}((${F.getJormTypeName()}) val);
#*   *##else
        this.${F.jormSetter()}((${F.getJormTypeName()}) ${F.getConvertClassName()}.toStorage(val));
#*   *##end
    }

    /*
    // Jorm Getter
    public ${F.getJormTypeName()} paGet${F.getNameUpperFirst()}() {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "return " + ${F.jormGetter()}());
#*   *##if (!$F.isMustBeConvert())
        return (${F.getJormTypeName()}) ${F.jormGetter()}();
#*   *##else
        return (${F.getJormTypeName()}) ${F.getConvertClassName()}.toStorage(${F.jormGetter()}());
#*   *##end
    }

    // Jorm Setter
    public void paSet${F.getNameUpperFirst()}(${F.getJormTypeName()} val) {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "param=" + val + " / current=" + ${F.jormGetter()}());
#*   *##if (!$F.isMustBeConvert())
        this.${F.jormSetter()}((${F.getTypeName()}) val);
#*   *##else
        this.${F.jormSetter()}((${F.getTypeName()}) ${F.getConvertClassName()}.toMemory(val));
#*   *##end
    }
    */

#end ##foreach
########################################################################
############ Accessors (EJB 2.0 & Jorm) for the CMR fields #############
########################################################################
#foreach ($F in $cmrList)
    //-------------------------------------------------------------//
    //------------------- Field  ${F.getName()}
    //-------------------------------------------------------------//

    private void update${F.getName()}() {
#*  *##if ($F.getRsr().isTargetMultiple())
        try {
            Object conn = factory.getConnection(null);
            ${F.jormSetter()}(((PNamingContext) factory.getPNameCoder("${F.getName()}"))
                              .export(conn, ${F.getName()}.gcGetPBinding(),
                                      ((PBinding) ejbContext.getEntitySwitch()).getPName()));
        } catch (PException e) {
            throw new RuntimeException("Impossible to fetch a PName of the '${F.getName()}' field", e);
        }
#*  *##else
        if (${F.getName()} != null) {
            ${F.jormSetter()}(((PObject) ${F.getName()}).getPName());
        } else {
            ${F.jormSetter()}(factory.getPNameCoder("${F.getName()}").getNull());
        }
#*  *##end
    }

#*  *##if (!$F.getRsr().isTargetMultiple())
    private void loadCMR${F.getUFLName()}() {
        if (${F.getName()} == null) {
            //TraceEjb.interp.log(BasicLevel.DEBUG,"load reference" + ${F.jormGetter()}());
            try {
                ${F.getName()} = (${F.getTypeName()}) getPObject(${F.jormGetter()}(), true);
            } catch (PException pe) {
                TraceEjb.logger.log(BasicLevel.ERROR, "impossible to load the reference", pe);
                throw new EJBException("Impossible to load the reference", pe);
            }
        }
    }

    private void clear${F.getUFLName()}() throws RemoveException {
        loadCMR${F.getUFLName()}();
        if (${F.getName()} != null) {
#*      *##if ($F.getRsr().mustCascade())
#*      *##else
            ((${F.getOppositeHelperFQClassName()}) ${F.getName()}).jonasSet${F.getOppositeUFLCMRName()}(null);
#*      *##end
        }
        ejbContext.setDirty(true);
        //        ${F.jormSetter()}(null);
        ${F.getName()} = null;
        update${F.getName()}();
    }

#*  *##else
    private void loadGC${F.getUFLName()}() {
        if (! ${F.getName()}loaded) {
            try {
                ${F.getName()}.read(${F.jormGetter()}(), null, jonasGetCurrentTransaction());
                ${F.getName()}loaded = true;
            } catch (PException pe) {
                Exception e = getInnerException(pe);
                TraceEjb.logger.log(BasicLevel.ERROR, "impossible to load the CMR field", e);
                throw new EJBException("Impossible to load the CMR field", e);
            }
        }
    }
#*  *##end

    // ------------------------  E J B   G E T T E R  ---------------------- //
    //-----------------------------------------------------------------------//
    public ${F.getTypeName()} get${F.getUFLName()}() {
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "bean pname:" + ((JEntitySwitch) ejbContext.getEntitySwitch()).getPrimaryKey());
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}=" + ${F.getName()});
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}PName=" + ${F.jormGetter()}());
        //if (${F.jormGetter()}() != null) {
        //    TraceEjb.interp.log(BasicLevel.DEBUG, "${F.getName()}PName.isNull(): " + ${F.jormGetter()}().isNull());
        //}
#*  *##if (!$F.getRsr().isTargetMultiple())
        loadCMR${F.getUFLName()}();
#*  *##else
        loadGC${F.getUFLName()}();
#*  *##end
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "return " + ${F.getName()});
        return ${F.getName()};
    }

    // ------------------------  E J B   S E T T E R  ---------------------- //
    //-----------------------------------------------------------------------//
    public void set${F.getUFLName()}(${F.getTypeName()} val) {
##
##
#*  *##if ($F.getRsr().isTargetMultiple())## MULTIVALUED ######################
        if (val == null) {
            throw new IllegalArgumentException("Assign a null value to a multivalued relationship");
        }
        loadGC${F.getUFLName()}();
        if (val != ${F.getName()}) {
            ejbContext.setDirty(true);
            // clear the current gen class
            ${F.getName()}.clear();

            // iterate over the parameter to add each element into the
            // current gen class
            for(Iterator it = val.iterator(); it.hasNext();) {
                ${F.getName()}.add(it.next());
            }
        }
##
##
#*  *##elseif ($F.isOOb())## ONE - ONE bidrectional############################
        // Load the reference for the coherence management
        loadCMR${F.getUFLName()}();
        if (val != null) {
            // Remove the relation of the bean which references the parameter
            // if there is a relation
            ${F.getHelperClassName()} element;
            try {
                element = ((${F.getOppositeHelperFQClassName()}) val).jonasGet${F.getOppositeUFLCMRName()}();
            } catch (NoSuchObjectLocalException e) {
                throw new IllegalArgumentException(e.getMessage());
            }
            if (element != null) {
                //TraceEjb.coherence.log(BasicLevel.DEBUG, "Remove the relation of the bean which references the parameter" + element);
                try {
                    element.jonasSet${F.getUFLName()}(null);
                } catch (Exception e) {
                    throw new EJBException("impossible to remove the relation of the bean which references the parameter", e);
                }
            }

            // link the parameter to the current bean (reverse relation coherence)
            //TraceEjb.coherence.log(BasicLevel.DEBUG, "link the parameter to the current bean");
            ${F.getHelperClassName()} current = (${F.getHelperClassName()})
#*      *##if ($dd.getLocalClass())
                                          ejbContext.get2EJBLocalObject();
#*      *##else
                                          ejbContext.getEJBObject();
#*      *##end
            if (current == null) {
                current = (${F.getHelperClassName()}) ejbContext.getEJBObject();
            }
            ((${F.getOppositeHelperFQClassName()}) val).jonasSet${F.getOppositeUFLCMRName()}(current);
        }

        // remove the relation of the current referenced bean to this
        if (${F.getName()} != null) {
            ((${F.getOppositeHelperFQClassName()}) ${F.getName()}).jonasSet${F.getOppositeUFLCMRName()}(null);
        }
        if (val == null || !val.equals(${F.getName()})) {
            ejbContext.setDirty(true);
            //            ${F.jormSetter()}(null);
            ${F.getName()} = val;
            update${F.getName()}();
        }
##
##
#*  *##elseif ($F.isMOb())## MANY - ONE bidrectional##########################
        loadCMR${F.getUFLName()}();
        if (val == null || !val.equals(${F.getName()})) {
            ${F.getHelperClassName()} current;
            try {
                current = (${F.getHelperClassName()})
#*      *##if ($dd.getLocalClass())
                                              ejbContext.get2EJBLocalObject();
#*      *##else
                                              ejbContext.getEJBObject();
#*      *##end
                if (${F.getName()} != null) {
                    ((${F.getOppositeHelperFQClassName()}) ${F.getName()}).jonasRemove${F.getOppositeUFLCMRName()}(current);
                }
                if (val != null) {
                    ((${F.getOppositeHelperFQClassName()}) val).jonasAdd${F.getOppositeUFLCMRName()}(current);
                }
            } catch (NoSuchObjectLocalException e) {
                throw new IllegalArgumentException(e.getMessage());
            }
            ejbContext.setDirty(true);
            //            ${F.jormSetter()}(null);
            ${F.getName()} = val;
            update${F.getName()}();
        }
##
##
#*  *##else####################################################################
        throw new EJBException("Error in generated Setter method");
#*  *##end
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "end: ${F.getName()}=" + ${F.getName()});
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "end: ${F.getName()}PName=" + ${F.jormGetter()}());
    }
##

    // -------------------  J O R M   A C C E S S O R S  ------------------- //
    //-----------------------------------------------------------------------//

    private PName ${F.jormGetter()}() {
        try {
            return super.${F.jormGetter()}((java.lang.Object) null);
        } catch (PException e) {
            throw new RuntimeException(e);
        }
    }

    private void ${F.jormSetter()}(PName pname) {
        try {
            super.${F.jormSetter()}(pname, (java.lang.Object) null);
        } catch (PException e) {
            throw new RuntimeException(e);
        }
    }

    // Jorm Getter
    public PName paGet${F.getUFLName()}(java.lang.Object conn)
                                                      throws PExceptionIO {
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}PName=" + ${F.jormGetter()}());
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}=" + ${F.getName()});
#*  *##if ($F.getRsr().isTargetMultiple())
        if (${F.jormGetter()}() == null) {
            try {
                ${F.jormSetter()}(((PNamingContext) factory.getPNameCoder("${F.getName()}"))
                                  .export(conn, ${F.getName()}.gcGetPBinding(),
                                          ((PBinding) ejbContext.getEntitySwitch()).getPName()));
            } catch (PExceptionIO e) {
                throw e;
            } catch (PException e) {
                throw new PExceptionIO(e, "Impossible to fetch a PName of the '${F.getName()}' field");
            }
        }
#*  *##else
        if (${F.jormGetter()}() == null) {
            if (${F.getName()} != null) {
                ${F.jormSetter()}(((PObject) ${F.getName()}).getPName());
            } else {
                ${F.jormSetter()}(factory.getPNameCoder("${F.getName()}").getNull());
            }
        }
#*  *##end
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"return " + ${F.jormGetter()}());
        return ${F.jormGetter()}();
    }

    // Jorm Setter
    public void paSet${F.getUFLName()}(PName o, java.lang.Object conn)
                                          throws PExceptionIO {
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"");
#*  *##if (!$F.getRsr().isTargetMultiple())
        this.${F.getName()} = null;
#*  *##end
        ${F.jormSetter()}(o);
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}PName: " + ${F.jormGetter()}());
        //if (${F.jormGetter()}() != null)
        //    TraceEjb.coherence.log(BasicLevel.DEBUG, "${F.getName()}PName.isNull(): " + ${F.jormGetter()}().isNull());
    }


    // IMPLEMENTATION OF THE ${F.getHelperFQClassName()} INTERFACE //
    //-------------------------------------------------------------//
#*  *##if ($F.getRsr().isTargetMultiple())#################################
    public ${F.getTypeName()} jonasGet${F.getUFLName()}() {
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"return " + ${F.getName()});
        loadGC${F.getUFLName()}();
        return ${F.getName()};
    }

    public void jonasSet${F.getUFLName()}(${F.getTypeName()} val) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"");
        if (val == null) {
            throw new IllegalArgumentException("Assign a null value to a relationship");
        }
        loadGC${F.getUFLName()}();
        if (val != ${F.getName()}) {
            ejbContext.setDirty(true);
            // clear the current gen class
            ${F.getName()}.clear();

            // iterate over the parameter to add each element into the
            // current gen class
            for (Iterator it = val.iterator(); it.hasNext(); ) {
                ${F.getName()}.add(it.next(), false);
            }
        }
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "END");
    }

    public void jonasAdd${F.getUFLName()}(${F.getOppositeHelperFQClassName()} bean) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "");
        loadGC${F.getUFLName()}();
        // In case of a MANY-MANY relation both gen class are mapped over the
        // the same hosting structure (rdb table). Then the coherence must be
        // done in memory in both sides, and in the support once time by the
        // master gen class.
        ${F.getName()}.add(bean, false);
    }

    public void jonasRemove${F.getUFLName()}(${F.getOppositeHelperFQClassName()} bean) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"");
        loadGC${F.getUFLName()}();
        // In case of a MANY-MANY relation both gen class are mapped over the
        // the same hosting structure (rdb table). Then the coherence must be
        // done in memory in both sides, and in the support once time by the
        // master gen class.
        ${F.getName()}.remove(bean, false);
    }

    public void jonasElemWritten${F.getUFLName()}(${F.getOppositeHelperFQClassName()} bean) {
        //${F.getName()}.doNotWrite((PObject) bean);
    }

#*  *##else## MONO VALUED FIELD#############################################
    public ${F.getOppositeHelperFQClassName()} jonasGet${F.getUFLName()}() {
        loadCMR${F.getUFLName()}();
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "return " + ${F.getName()});
        return (${F.getOppositeHelperFQClassName()}) ${F.getName()};
    }

    public void jonasSet${F.getUFLName()}(${F.getOppositeHelperFQClassName()} val) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG,"");
        if (val == null || !val.equals(${F.getName()})) {
            ejbContext.setDirty(true);
            //            ${F.jormSetter()}(null);
            ${F.getName()} = (${F.getTypeName()}) val;
            update${F.getName()}();
        }
    }
#*  *##end##


#end##foreach

#foreach ($M in $methodList)

###############################################
############## ejbActivate ################
###############################################
#if ($M.isEjbActivate())
    /*
     * ejbActivate() method
     */
    public void ejbActivate()
#*  *##if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#*  *##end
        {
            setPkAllowed = false;
            super.ejbActivate();
        }

###############################################
############## setEntityContext ################
###############################################
#elseif ($M.isEjbSetEntityContext())
    /*
     * setEntityContext(javax.ejb.EntityContext) method
     */
    public void setEntityContext(javax.ejb.EntityContext p1)
#*  *##if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#*  *##end
        {
            setPkAllowed = false;
            ejbContext = (JEntityContext) p1;
            if (factory == null) {
                factory = (MedorFactory) ejbContext.getEntityFactory();
                PClassMapping gcm = null;
                selectForUpdate = factory.getSelectForUpdate();
#*  *##foreach ($F in $cmrList)
#*      *##if ($F.getRsr().isTargetMultiple())
                //initialize the multivalued relation ${F.getName()}
                ${F.getName()} = new ${F.getGenClassName()}();
                gcm = factory.getGenClassMapping("${F.getName()}");
                ${F.getName()}.setPClassMapping(gcm);
                ${F.getName()}.setEntityContext(ejbContext);
                ${F.getName()}.setListener(new ${F.getName()}Of${dd.getEjbName()}Listener(this));
                try {
                    ${F.getName()}.setPBinding(gcm.createPBinding());
                } catch (PException e) {
                    TraceEjb.interp.log(BasicLevel.ERROR,
                                        "Impossible to create a PBinding for the relation ${F.getName()}", e);
                    throw new EJBException("Impossible to create a PBinding for the relation ${F.getName()}", e);
                }
#*      *##end
#*  *##end
            }
            super.setEntityContext(p1);
        }

#########################################
############## EjbCreate ################
#########################################
#elseif ($M.isEjbPostCreate())
    /*
     * ejbPostCreate(.....) method
     */
    public void $M.getName()($M.getFormalParameters())
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
    {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "differed writing at create");
        super.$M.getName()($M.getActualParameters());
        PBinding pb = (PBinding) ejbContext.getEntitySwitch();
        Object conn = null;
        try {
            conn = factory.getConnection(null);
            ejbContext.setDirty(false);
            pb.write(conn, this);
        } catch (Exception e) {
            TraceEjb.logger.log(BasicLevel.ERROR,
                                "Failed to create bean: ", getInnerException(e));
            throw new EJBException("Failed to create bean: " + getInnerException(e).getMessage());
        } finally {
            try {
                if (conn != null)
                    factory.releaseConnection(conn);
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
            }
        }
    }

#elseif ($M.isEjbCreate())
    /*
     * ejbCreate(.....) method
     */
    public PName _$M.getName()($M.getFormalParameters())
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
        {
            //TraceEjb.interp.log(BasicLevel.DEBUG,"");
            // Container-managed fields must be set to the Java language default values
#foreach ($F in $fieldList)
            this.${F.jormSetter()}($F.getDefaultValue());
#end
#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
            ${F.getName()}.reset();
            ${F.jormSetter()}(null);
#*  *##else
            jonasSet${F.getUFLName()}(null);
#*  *##end
#end
            setPkAllowed = true;
            super.${M.getName()}(${M.getActualParameters()});

#if ( $IsAutomaticPk || $IsUndefinedPK ) // If Pk is auto-incremented, we must set the value of the pk
            // Only type Integer is valid
            this.$pkField(new Integer(factory.calculateAutomaticPk()));
#end
            setPkAllowed = false;
            PBinding pb = (PBinding) ejbContext.getEntitySwitch();
            //TraceEjb.interp.log(BasicLevel.DEBUG, "pb=" + pb);
            Object conn = null;
            try {
                conn = factory.getConnection(null);
#if($pkIsUserClass)
                pb.export(conn, this);
#else
                pb.export(conn, JavaType.toObject(get${fieldPkList.elementAt(0).getNameUpperFirst()}()));
#end
                //TraceEjb.interp.log(BasicLevel.DEBUG, "PName=" + pb.getPName());
                // The write operation has been differed in the postCreate, to resolve the
                // issue when a legacy database has "not null" foreign keys.
                return pb.getPName();
            } catch (PExceptionExistingDSI pe) {
                throw new DuplicateKeyException(pe.getMessage());
            } catch (PExceptionExistingName pe) {
                throw new DuplicateKeyException(pe.getMessage());
            } catch (PExceptionNaming pe) {
                throw new CreateException("The pk fields has not been initialized the ejbCreate method of the bean ${dd.getEjbName()}");
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR,
                                    "Failed to create bean: ", getInnerException(e));
                throw new CreateException("Failed to create bean: " + getInnerException(e).getMessage());
            } finally {
                try {
                    if (conn != null)
                        factory.releaseConnection(conn);
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
                }
            }
        }

##########################################
############## FinderByPk ################
##########################################
#elseif ($M.isFinderByPk())
    /*
     * ejbFindByPrimaryKey(...) method
     */
    public PName ejbFindByPrimaryKey($pk pk)
        throws FinderException {
        // Translate the pk into a PName
        Coder c = (Coder) ejbContext.getEntityFactory().getLocalHome();
        if (c == null) {
            c = (Coder) ejbContext.getEntityFactory().getHome();
        }
        PName pn = null;
        try {
            pn = c.decode(pk);
        } catch (Exception e) {
            TraceEjb.logger.log(BasicLevel.ERROR,
                                "Failed to decode the primary key:" + pk, e);
            throw new FinderException("Failed to decode the primary key:" + pk);
        }
        return ejbFindByPrimaryKey(pn);
    }

    /*
     * ejbFindByPrimaryKey(...) method
     */
    public PName ejbFindByPrimaryKey(PName pn)
        throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, pn);
        PBinding pb = (PBinding) ejbContext.getEntitySwitch();
        //TraceEjb.interp.log(BasicLevel.DEBUG, "pb=" + pb);
        //TraceEjb.interp.log(BasicLevel.DEBUG, "pb.getStatus()=" + pb.getStatus());
        Object conn = null;
        try {
            conn = factory.getConnection(null);
            pb.bind(pn);
            if (!pb.exist(conn)) {
             //   TraceEjb.interp.log(BasicLevel.DEBUG,
             //                       "Object not found in database (ejbFindByPrimaryKey("
             //                       + pn + "))");
                pb.unbind();
                throw new ObjectNotFoundException("Object not found in database (ejbFindByPrimaryKey(" + pn + "))");
            }
            return pn;
        } catch (ObjectNotFoundException oe) {
            throw oe;
        } catch (Exception e) {
            TraceEjb.logger.log(BasicLevel.ERROR,
                                "Failed to find bean from database in ejb$M.getCapName()" + pn,
                                getInnerException(e));
            throw new FinderException("Failed to find bean from database in ejb$M.getCapName()");
        } finally {
            //TraceEjb.interp.log(BasicLevel.DEBUG, "pb.getStatus()=" + pb.getStatus());
            try {
                if (conn != null)
                    factory.releaseConnection(conn);
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
            }
        }
    }

#########################################
############## EjbRemove ################
#########################################
#elseif ($M.isEjbRemove())

    private boolean ejbRemoveCalled = false;

    /*
     * ejbRemove() method
     * This implementation unexports the bean, and remove the data on the
     * support.
     */
    public void ejbRemove()
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
        {
            if (ejbRemoveCalled) {
                // In case of cascade delete loops.
                return;
            }
            ejbRemoveCalled = true;
        try {
            //TraceEjb.interp.log(BasicLevel.DEBUG, "");
            super.ejbRemove();

#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().mustCascade())
#*      *##if ($F.getRsr().isTargetMultiple())
            loadGC${F.getUFLName()}();
            for (Iterator it = ${F.getName()}.iterator(); it.hasNext();) {
                javax.ejb.EJBLocalObject el = (javax.ejb.EJBLocalObject) it.next();
                el.remove();
            }
#*      *##else
            loadCMR${F.getUFLName()}();
            if (${F.getName()} != null) {
                ${F.getName()}.remove();
            }
#*      *##end
#*  *##end
#end

#foreach ($F in $cmrList)
#*  *##if ($F.isMMb()) ## MANY - MANY bidirectional
            loadGC${F.getUFLName()}(); // needed for coherence of remove.
            ${F.getName()}.clear(); // MM
#*  *##elseif ($F.isOMb()) ## ONE - MANY bidirectional
            loadGC${F.getUFLName()}(); // needed for coherence of remove.
            ${F.getName()}.gcClear(true); // OM
#*  *##elseif ($F.isMOb()) ## MANY - ONE bidirectional
            set${F.getUFLName()}(null); // MO
#*  *##else
            clear${F.getUFLName()}(); // OO
#*  *##end
#end
        } finally {
            ejbRemoveCalled = false;	// in case of rollback
        }
            PBinding pb = (PBinding) ejbContext.getEntitySwitch();
            Object conn = null;
            try {
                conn = factory.getConnection(null);
                PName pn = (PName) ((JEntitySwitch) pb).getPrimaryKey();

                //TraceEjb.interp.log(BasicLevel.DEBUG, "Remove the bean " + pn);
                pb.bind((PName) ((JEntitySwitch) pb).getPrimaryKey());
                pb.unexport(conn);
                pb.write(conn, this);
                //pb.unbind();

#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
                //TraceEjb.interp.log(BasicLevel.DEBUG, "Remove the multivalued CMR ${F.getName()}");
                if (${F.jormGetter()}() == null) {
                    ${F.jormSetter()}(((PNamingContext) factory.getPNameCoder("${F.getName()}"))
                                      .export(conn, ${F.getName()}.gcGetPBinding(), pn));
                }
                pb = ${F.getName()}.gcGetPBinding();
                pb.bind(${F.jormGetter()}());
                pb.unexport(conn);
                ${F.getName()}.write(${F.jormGetter()}(), conn);
                //pb.unbind();
#*  *##end
#end
                ejbContext.setDirty(false);
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to remove", getInnerException(e));
#if ( $M.getExceptionList().indexOf("RemoveException") != -1 )
                throw new RemoveException(e.getMessage());
#else
                throw new EJBException(e.getMessage());
#end
        } finally {
                try {
                    if (conn != null)
                        factory.releaseConnection(conn);
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
                }
            }
        }

#######################################
############## EjbLoad ################
#######################################
#elseif ($M.isEjbLoad())
    /*
     * ejbLoad() method
     */
    public void ejbLoad()
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
        {
            Object conn = null;
            PBinding pb = (PBinding) ejbContext.getEntitySwitch();
            try {
                conn = factory.getConnection(null);
                pb.bind((PName) ((JEntitySwitch) pb).getPrimaryKey());
                pb.read(conn, this, jonasGetCurrentTransaction(), selectForUpdate);
##
## Be careful the relations must be load after the bean, because the PNames of
## the gen class are assigned by the paSetXXX methods.
##
#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
                // lazy loading of the multivalued relations ${F.getName()}
                ${F.getName()}loaded = false;
#*  *##end
#end
                ejbContext.setDirty(false);
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Jorm could not load bean instance");
                throw new EJBException(getInnerException(e));
            } finally {
                //TraceEjb.interp.log(BasicLevel.DEBUG, "pb.getStatus()=" + pb.getStatus());
                try {
                    if (conn != null)
                        factory.releaseConnection(conn);
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
                }
            }
            super.ejbLoad();
        }

########################################
############## EjbStore ################
########################################
#elseif ($M.isEjbStore())
    /*
     * ejbStore() method
     */
    public void ejbStore()
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
        {
            // bean method must be called in any case (spec EJB)
            super.ejbStore();
            if (ejbContext.isDirty()
#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
                || ${F.getName()}.gcIsModified()
#*  *##end
#end
                ) {
                // The bean or a gen class has been modified
                // ==> The first allocates a connection which will be shared to
                // store the modified objects
                Object conn = null;
                //TraceEjb.interp.log(BasicLevel.DEBUG, "");
                try {
                    PName pn = null;
                    if (ejbContext.isDirty()) {
                        //TraceEjb.interp.log(BasicLevel.DEBUG, "Store the bean");
                        conn = factory.getConnection(null);
                        // The bean has been modified
                        PBinding pb = (PBinding) ejbContext.getEntitySwitch();
                        pn = (PName) ((JEntitySwitch) pb).getPrimaryKey();
                        pb.bind(pn);
                        // try a fix for #306186 : Don't set dirty when
                        // write raised an exception.
                        ejbContext.setDirty(false);
                        pb.write(conn, this);
                    }
#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
                    if (${F.getName()}.gcIsModified()) {
                        if (${F.jormGetter()}()==null) {
                            if (pn == null)
                                pn = (PName) ejbContext.getEntitySwitch().getPrimaryKey();
                            try {
                                ${F.jormSetter()}(((PNamingContext) factory.getPNameCoder("${F.getName()}"))
                                                  .export(conn, ${F.getName()}.gcGetPBinding(), pn));
                            } catch (PExceptionIO e) {
                                throw e;
                            } catch (PException e) {
                                throw new PExceptionIO(e, "Impossible to fetch a PName of the '${F.getName()}' field");
                            }
                        }
                        //TraceEjb.interp.log(BasicLevel.DEBUG, "Store the gen class ${F.getName()}");
                        if (conn == null)
                            conn = factory.getConnection(null);
                        // store the multivalued relations ${F.getName()}
                        // because it has been modified
                        ${F.getName()}.write(${F.jormGetter()}(), conn);
                    }
#*  *##end
#end
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to store", getInnerException(e));
                    throw new EJBException(e);
                } finally {
                    try {
                        if (conn != null)
                            factory.releaseConnection(conn);
                    } catch (Exception e) {
                        TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
                    }
                }
            }
        }

############################################
############## FinderSimple ################
############################################
#elseif ($M.isFinderSimple())
    /*
     * ejbFindXXX(...) method returning only 1 PK
     */
    public PName ejb$M.getCapName()($M.getFormalParameters())
        throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        TupleCollection tc = null;
        Object conn = null;
        try {
            ParameterOperand[] params = new BasicParameterOperand[${M.getParametersNumber()}];
#*          *##set($pc = 1)## The parameter counter starts always to 1
#*          *##set($idx = 0)## the array index starts to 0
#*          *##foreach($t in $M.getParamList())
#*          *##if (${t.isEjbLocal()})
            // EJBLocalObject param case
            if (p$pc == null) {
                PClassMapping pcm = (PClassMapping) factory.getContainer().getBeanFactory("${t.getEjbName()}");
                params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                         "?$pc",
                                                         pcm.getPBinder().getNull());
            } else {
                params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                         "?$pc",
                                                         ((PObject) p$pc).getPName());
            }
#*          *##else
            params[$idx] = new BasicParameterOperand(${t.getJormType()}, "?$pc", p$pc);
#*          *##end
#*              *##set($idx = $idx + 1)
#*              *##set($pc = $pc + 1)
#*          *##end

              conn = factory.getConnection(null);

            tc = factory.evaluate(conn, ${M.getMethodIndex()}, params);

            //Build the result
            if (tc.isEmpty()) {
               // TraceEjb.interp.log(BasicLevel.DEBUG,
               //                     "The bean was not found in the support");
                throw new ObjectNotFoundException("The bean was not found in the support");
            } else {
                PName pn = (PName) tc.getTuple().getObject(tc.getMetaData().getSize());
                //TraceEjb.interp.log(BasicLevel.DEBUG, "pn: " + pn);
                if (!tc.isLast()) {
                    throw new FinderException("There is more than one object in response to the ${M.getCapName()} single-object finder");
                } else {
                    return pn;
                }
            }
        } catch (PException e) {
            TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the finder method ${M.getCapName()}", getInnerException(e));
            throw new FinderException("An error occured during the evaluation of the ${M.getCapName()} request:"
                                      + e.getMessage());
        } catch (MedorException e) {
            TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the finder method ${M.getCapName()}", getInnerException(e));
            throw new FinderException("An error occured during the evaluation of the ${M.getCapName()} request:"
                                      + e.getMessage());
        } finally {
            if (tc != null) {
                try {
                    tc.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the TupleCollection in the finder method ${M.getCapName()}",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    factory.releaseConnection(conn);
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "impossible to close a connection", e);
                }
            }
        }
        //look in the interposition objects (local or remote) the return type !!!
    }


#elseif ($M.isFinderEnum() || $M.isFinderCol())
##########################################
############## isFinderAll ###############
##########################################
#**##if ($M.isFinderAll())
    public $M.getReturnType() ejb$M.getCapName()($M.getFormalParameters())
        throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        Object conn = null;
        try {
            conn = factory.getConnection(null);
            ArrayList beans = new ArrayList();
            for (Iterator it = factory.getPNameIterator(conn); it.hasNext(); ) {
                beans.add(it.next());
            }
#*          *##if ($M.isFinderEnum()) ## the result is an Enumeration
            return java.util.Collections.enumeration(beans);
#*          *##else ## the result is a collection
            return beans;
#*          *##end
        } catch (Exception e) {
            TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to find all objects", getInnerException(e));
            throw new FinderException("Impossible to find all objects" + e);
        } finally {
            try {
                if (conn != null) {
                    factory.releaseConnection(conn);
                }
            } catch (Exception e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Impossible to release connection", e);
            }
        }
    }
##########################################
####### FinderEnum or FinderColl##########
##########################################
#**##else
    /*
     * ejbFindXXX(...) method returning a java.util.Enumeration or a java.util.Collection
     */
    public $M.getReturnType() ejb$M.getCapName()($M.getFormalParameters())
        throws FinderException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "");
        TupleCollection tc = null;
        Object conn = null;
        try {
            ParameterOperand[] params = new BasicParameterOperand[${M.getParametersNumber()}];
#*          *##set($pc = 1)## The parameter counter starts always to 1
#*          *##set($idx = 0)## the array index starts to 0
#*          *##foreach($t in $M.getParamList())
#*          *##if (${t.isEjbLocal()})
            // EJBLocalObject param case
            if (p$pc == null) {
                PClassMapping pcm = (PClassMapping) factory.getContainer().getBeanFactory("${t.getEjbName()}");
                params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                         "?$pc",
                                                         pcm.getPBinder().getNull());
            } else {
                params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                         "?$pc",
                                                         ((PObject) p$pc).getPName());
            }
#*          *##else
            params[$idx] = new BasicParameterOperand(${t.getJormType()}, "?$pc", p$pc);
#*          *##end
#*              *##set($idx = $idx + 1)
#*              *##set($pc = $pc + 1)
#*          *##end
              conn = factory.getConnection(null);
            tc = factory.evaluate(conn, ${M.getMethodIndex()}, params);
            // Build the result
            ArrayList result = new ArrayList();
            if (!tc.isEmpty()) {
                do {
                    result.add(tc.getTuple().getObject(tc.getMetaData().getSize()));
                } while (tc.next());
            }
#*          *##if ($M.isFinderEnum())
            return Collections.enumeration(result);
#*          *##else
            return result;
#*          *##end
        } catch (PException e) {
            TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of ${M.getCapName()}", e);
            throw new FinderException("An error occured during the evaluation of the ${M.getCapName()} request:"
                                      + e.getMessage());
        } catch (MedorException e) {
            TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of ${M.getCapName()}", e);
            throw new FinderException("An error occured during the evaluation of the ${M.getCapName()} request:"
                                      + e.getMessage());
          } finally {
            if (tc != null) {
                try {
                    tc.close();
                } catch (Exception ignore) {
                    TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the TupleCollection in the finder method ${M.getCapName()}",
                                        ignore);
                }
            }
            if (conn != null) {
                try {
                    factory.releaseConnection(conn);
                } catch (Exception e) {
                    TraceEjb.logger.log(BasicLevel.ERROR, "impossible to close a connection", e);
                }
            }
        }
    }
#**##end

############################################
############## ejbSelect Simple|Set|Col ####
############################################
#elseif ($M.isEjbSelectSimple() || $M.isEjbSelectSet() || $M.isEjbSelectCol())
    /*
     * ejbSelectXXX(...) method
     */
    public $M.getReturnType() $M.getName()($M.getFormalParameters())
#if ( $M.getExceptionList().length() > 0 )
        throws $M.getExceptionList()
#end
        {
            //TraceEjb.interp.log(BasicLevel.DEBUG, "");
            factory.syncForSelect();
############ ejbSelect returning a remote bean or a local bean ##############
#*   *##if ( $M.isEjbqlReturnRemoteBean() || $M.isEjbqlReturnLocalBean() )
#*        *##set( $returnLocalBean = $M.isEjbqlReturnLocalBean() )
            TupleCollection tc = null;
            Object conn = null;
            try {
                // Build the query paramaters list
                ParameterOperand[] params = new BasicParameterOperand[${M.getParametersNumber()}];
#*           *##set($pc = 1)## The parameter counter starts always to 1
#*           *##set($idx = 0)## the array index starts at 0
#*           *##foreach($t in $M.getParamList())
#*              *##if (${t.isEjbLocal()})
                // EJBLocalObject param case
                if (p$pc == null) {
                    PClassMapping pcm = (PClassMapping) factory.getContainer().getBeanFactory("${t.getEjbName()}");
                    params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                             "?$pc",
                                                             pcm.getPBinder().getNull());
                } else {
                    params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                             "?$pc",
                                                             ((PObject) p$pc).getPName());
                }
#*              *##else
                params[$idx] = new BasicParameterOperand(${t.getJormType()}, "?$pc", p$pc);
#*              *##end
#*              *##set($idx = $idx + 1)
#*           *##set($pc = $pc + 1)
#*           *##end  ##foreach
                  conn = factory.getConnection(null);
                // Evaluate the query
                tc = factory.evaluate(conn, ${M.getMethodIndex()}, params);
                //Build the result
#*           *##if ($M.isEjbSelectSimple())
                if (tc.isEmpty()) {
                   // TraceEjb.interp.log(BasicLevel.DEBUG,
                   //                     "No value was not found in the support");
                    throw new ObjectNotFoundException("No value was not found in the support");
                } else {
                    PName pn = (PName) tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize());
                    ${M.getReturnType()} rValue = (${M.getReturnType()}) getPObject(pn, $returnLocalBean);
                    if (!tc.isLast()) {
                        throw new FinderException("There is more than one value in response to the ${M.getName()} single-value ejbSelect");
                    } else {
                        return rValue;
                    }
                }
#*           *##elseif ($M.isEjbSelectSet())
                HashSet result = new HashSet();
                if (!tc.isEmpty()) {
                    do {
                        PName pn = (PName) tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize());
                        Object po = getPObject(pn, $returnLocalBean);
                        if (!result.contains(po)) {
                            result.add(po);
                        }
                    } while (tc.next());
                }
                return result;
#*           *##elseif ($M.isEjbSelectCol())
                ArrayList result = new ArrayList();
                if (!tc.isEmpty()) {
                    do {
                        PName pn = (PName) tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize());
                        result.add(getPObject(pn, $returnLocalBean));
                    } while (tc.next());
                }
                return result;
#*           *##end ##elseif isEjbSelectCol()
            } catch (PException e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the ejbSelect method ${M.getName()}", e);
                throw new FinderException(
                                          "An error occured during the evaluation of the ${M.getName()} request:"
                                          + e.getMessage());
            } catch (MedorException e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the ejbSelect method ${M.getName()}", getInnerException(e));
                throw new FinderException(
                                          "An error occured during the evaluation of the ${M.getName()} request:"
                                          + e.getMessage());
            } finally {
                if (tc != null) {
                    try {
                        tc.close();
                    } catch (Exception ignore) {
                        TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the TupleCollection in the finder method ${M.getName()}",
                                            ignore);
                    }
                }
                if (conn != null) {
                    try {
                        factory.releaseConnection(conn);
                    } catch (Exception e) {
                        TraceEjb.logger.log(BasicLevel.ERROR, "impossible to close a connection", e);
                    }
                }


            }

############ ejbSelect returning neither a remote bean nor a local bean ##############
#*   *##else
            TupleCollection tc = null;
            Object conn = null;
            try {
                // Build the query parameters list
                ParameterOperand[] params = new BasicParameterOperand[${M.getParametersNumber()}];
#*           *##set($pc = 1)## The parameter counter starts always to 1
#*           *##set($idx = 0)## the array index starts at 0
#*           *##foreach($t in $M.getParamList())
#*             *##if (${t.isEjbLocal()})
                // EJBLocalObject param case
                if (p$pc == null) {
                    PClassMapping pcm = (PClassMapping) factory.getContainer().getBeanFactory("${t.getEjbName()}");
                    params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                             "?$pc",
                                                             pcm.getPBinder().getNull());
                } else {
                    params[$idx] = new BasicParameterOperand(PTypeSpaceMedor.PNAME,
                                                             "?$pc",
                                                             ((PObject) p$pc).getPName());
                }
#*             *##else
                params[$idx] = new BasicParameterOperand(${t.getJormType()}, "?$pc", p$pc);
#*             *##end
#*           *##set($idx = $idx + 1)
#*           *##set($pc = $pc + 1)
#*           *##end  ##foreach
                // Evaluate the query
                  conn = factory.getConnection(null);
                tc = factory.evaluate(conn, ${M.getMethodIndex()}, params);
                //Build the result
#*           *##if ($M.isEjbSelectSimple())
                if (tc.isEmpty()) {
                    //TraceEjb.interp.log(BasicLevel.DEBUG,
                    //                    "No value was not found in the support");
                    throw new ObjectNotFoundException("No value was not found in the support");
                } else {
                    ${M.getReturnType()} rValue = (${M.getReturnType()}) tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize());
                    // tc.next() causes a NPE with postgres
                    if (!tc.isLast()) {
                        throw new FinderException("There is more than one value in response to the ${M.getName()} single-value ejbSelect");
                    } else {
                        return rValue;
                    }
                }
#*           *##elseif ($M.isEjbSelectSet())
                HashSet result = new HashSet();
                if (!tc.isEmpty()) {
                    do {
                        boolean ignoreNull = false;
#*                  *##if ($M.isTupleGetterPrimitive())
                        ignoreNull = tc.getTuple().isDefined(tc.getMetaData().getSize());
                        Object o = new $M.getTupleGetterObjectClass()(tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize()));
#*                  *##else
                        Object o = tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize());
#*                  *##end
                        if (!ignoreNull && !result.contains(o)) {
                            result.add(o);
                        }
                    } while (tc.next());
                }
                return result;
#*           *##elseif ($M.isEjbSelectCol())
                ArrayList result = new ArrayList();
                if (!tc.isEmpty()) {
                    do {
#*                  *##if ($M.isTupleGetterPrimitive())
                        // ignore null values
                        if (tc.getTuple().isDefined(tc.getMetaData().getSize())) {
                            result.add(new $M.getTupleGetterObjectClass()(tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize())));
                        }
#*                  *##else
                        result.add(tc.getTuple().${M.getTupleGetter()}(tc.getMetaData().getSize()));
#*                  *##end
                    } while (tc.next());
                }
                return result;
#*           *##end  ##elseif isEjbSelectCol()
            } catch (PException e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the ejbSelect method ${M.getName()}", getInnerException(e));
                throw new FinderException(
                                          "An error occured during the evaluation of the ${M.getName()} request:"
                                          + e.getMessage());
            } catch (MedorException e) {
                TraceEjb.logger.log(BasicLevel.ERROR, "Problem during the evaluation of the ejbSelect method ${M.getName()}", getInnerException(e));
                throw new FinderException(
                                          "An error occured during the evaluation of the ${M.getName()} request:"
                                          + e.getMessage());
            } finally {
                if (tc != null) {
                    try {
                        tc.close();
                    } catch (Exception ignore) {
                        TraceEjb.interp.log(BasicLevel.ERROR,"failed to close the TupleCollection in the finder method ${M.getName()}",
                                            ignore);
                    }
                }
                if (conn != null) {
                    try {
                        factory.releaseConnection(conn);
                    } catch (Exception e) {
                        TraceEjb.logger.log(BasicLevel.ERROR, "impossible to close a connection", e);
                    }
                }
            }

#*   *##end  ##else elseif isEjbqlReturnRemoteBean()
        }

#end ##elseif
#end ##foreach method

##########################################
############## getPObject ################
##########################################
    /**
     * This method is used to reach a referenced bean with its pname.
     */
    private Object getPObject(PName pn, boolean useLocal) throws PException {
        //TraceEjb.interp.log(BasicLevel.DEBUG, "Search PObject with the pnane:" + pn);
        if (pn == null || pn.isNull()) {
            return null;
        }
        PBinder f = (PBinder) pn.getPNameManager();
        JEntityFactory ef = (JEntityFactory) f.getBinderClassMapping();
        if (useLocal) {
            return ((PObjectHome) ef.getLocalHome()).getPObject(pn);
        } else {
            return ((PObjectHome) ef.getHome()).getPObject(pn);
        }
    }

    // IMPLEMENTATION OF THE PAccessor INTERFACE //

    public Object getMemoryInstance() {
        return this;
    }

    private static Exception getInnerException(Exception e) {
        boolean last = false;
        Exception res = e;
        while (!last) {
            if (res instanceof PException
                && ((PException) res).getNestedException() != null) {
                res = ((PException) res).getNestedException();

            } else if (res instanceof MedorException
                       && ((MedorException) res).getNestedException() != null) {
                res = ((MedorException) res).getNestedException();

            } else if (res instanceof EJBException
                       && ((EJBException) res).getCausedByException() != null) {
                res = ((EJBException) res).getCausedByException();

            } else
                last = true;
        }
        return res;
    }
#if($pkIsUserClass)
    // IMPLEMENTATION OF THE ${dd.getJormPNameGetterClassName()} INTERFACE //
#*  *##foreach ($pkf in $fieldPkList)
    public ${pkf.getJormTypeName()} pnGet${pkf.getNameUpperFirst()}(Object ctx) {
#*   *##if (!$pkf.isMustBeConvert())
        return (${pkf.getJormTypeName()}) ${pkf.jormGetter()}();
#*   *##else
        return (${pkf.getJormTypeName()}) ${pkf.getConvertClassName()}.toStorage(${pkf.jormGetter()}());
#*   *##end
    }
#*  *##end
#end

    private Object jonasGetCurrentTransaction() {
        try {
            Object tx = factory.getTransactionManager().getTransaction();
            //TraceEjb.logger.log(BasicLevel.DEBUG, "current transaction=" + tx);
            //new Exception("Current Transaction=" + tx).printStackTrace();
            return tx;
        } catch (javax.transaction.SystemException e) {
            TraceEjb.logger.log(BasicLevel.ERROR,
                "Cannot get the current transaction to do the read:", e);
            //System.out.println("No current Transaction: " + e.getMessage());
            return null;
        }
    }
}


#foreach ($F in $cmrList)
#*  *##if ($F.getRsr().isTargetMultiple())
/**
 * Listener on modifications made on ${F.getName()}
 */
class ${F.getName()}Of${dd.getEjbName()}Listener implements GenClassListener {

    private $class bean;

    protected ${F.getName()}Of${dd.getEjbName()}Listener($class bean) {
        this.bean = bean;
    }

    public void isLegalElement(GenClassElement gce) throws IllegalArgumentException {
        try {
            Object o = (${F.getOppositeHelperFQClassName()}) gce.value;
        } catch (ClassCastException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    /**
     * An Element has been added
     */
    public void gcAdd(GenClassElement gce) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "gce.value=" + gce.value);
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "gce.pname=" + gce.pname);
##
## ONE - MANY bidrectional
##
#*      *##if ($F.isOMb())
       ${F.getHelperFQClassName()} localBean =
                                        ((${F.getOppositeHelperFQClassName()}) gce.value)
                                        .jonasGet${F.getOppositeUFLCMRName()}();
        if (localBean != null) {
            //TraceEjb.coherence.log(BasicLevel.DEBUG, "remove the old relation with the element (" + localBean + ")");
            localBean.jonasRemove${F.getUFLName()}((${F.getOppositeHelperFQClassName()}) gce.value);
        }
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "Assign the opposite cmr field(set this)");
        ((${F.getOppositeHelperFQClassName()}) gce.value)
            .jonasSet${F.getOppositeUFLCMRName()}((${F.getHelperFQClassName()})
#*          *##if ($dd.getLocalClass())
                                                  bean.ejbContext.get2EJBLocalObject()
#*          *##else
                                                  bean.ejbContext.getEJBObject()
#*          *##end
                                                  );
#*      *##end

##
## MANY - MANY bidrectional
##
#*      *##if ($F.isMMb())
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "Assign the opposite cmr field (add this)");
        ((${F.getOppositeHelperFQClassName()}) gce.value)
            .jonasAdd${F.getOppositeUFLCMRName()}((${F.getHelperFQClassName()})
#*          *##if ($dd.getLocalClass())
                                                  bean.ejbContext.get2EJBLocalObject()
#*          *##else
                                                  bean.ejbContext.getEJBObject()
#*          *##end
                                                  );
#*      *##end
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "END");
    }

    /**
     * An element has been removed
     */
    public void gcRemove(GenClassElement gce, boolean delete) {
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "gce.value=" + gce.value);
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "gce.pname=" + gce.pname);
##
## ONE - MANY bidrectional
##
#*      *##if ($F.isOMb())

        ((${F.getOppositeHelperFQClassName()}) gce.value).jonasSet${F.getOppositeUFLCMRName()}(null);
#*      *##end

##
## MANY - MANY bidrectional
##
#*      *##if ($F.isMMb())
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "Modify the opposite cmr field (remove this)");
        ((${F.getOppositeHelperFQClassName()}) gce.value)
            .jonasRemove${F.getOppositeUFLCMRName()}((${F.getHelperFQClassName()})
#*          *##if ($dd.getLocalClass())
                                                     bean.ejbContext.get2EJBLocalObject()
#*          *##else
                                                     bean.ejbContext.getEJBObject()
#*          *##end
                                                     );
#*      *##end
        //TraceEjb.coherence.log(BasicLevel.DEBUG, "END");
    }
}
#*  *##end## relation multivalued
#end## foreach CMR

