Coverage Report - org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
SequenceManagerNextValImpl
N/A
N/A
2.2
 
 1  
 package org.apache.ojb.broker.util.sequence;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.sql.ResultSet;
 19  
 import java.sql.Statement;
 20  
 import java.sql.PreparedStatement;
 21  
 
 22  
 import org.apache.commons.lang.SystemUtils;
 23  
 import org.apache.ojb.broker.PersistenceBroker;
 24  
 import org.apache.ojb.broker.accesslayer.StatementManagerIF;
 25  
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 26  
 import org.apache.ojb.broker.metadata.FieldDescriptor;
 27  
 import org.apache.ojb.broker.query.Query;
 28  
 import org.apache.ojb.broker.util.logging.Logger;
 29  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 30  
 
 31  
 /**
 32  
  * This SequenceManager implementation uses database
 33  
  * sequence key generation (e.g supported by
 34  
  * Oracle, SAP DB, PostgreSQL, ...).
 35  
  * This class is responsible for creating new unique ID's.
 36  
  * <br/>
 37  
  * It is possible to define a <code>sequence-name</code>
 38  
  * field-descriptor attribute in the repository file. If
 39  
  * such an attribute was not found, the implementation build
 40  
  * an extent aware sequence name by its own.
 41  
  * <br/>
 42  
  * Keep in mind when define a sequence name, that you are responsible
 43  
  * to be aware of extents, that is: if you ask for an uid for an
 44  
  * interface with several
 45  
  * implementor classes, or a baseclass with several subclasses the returned
 46  
  * uid have to be unique accross all tables representing objects of the
 47  
  * extent in question. Thus you have to use the same <code>sequence-name</code>
 48  
  * for all extents.
 49  
  *
 50  
  * <p>
 51  
  * Implementation configuration properties:
 52  
  * </p>
 53  
  *
 54  
  * <table cellspacing="2" cellpadding="2" border="3" frame="box">
 55  
  * <tr>
 56  
  *     <td><strong>Property Key</strong></td>
 57  
  *     <td><strong>Property Values</strong></td>
 58  
  * </tr>
 59  
  * <tr>
 60  
  *     <td>autoNaming</td>
 61  
  *     <td>
 62  
  *          Default was 'true'. If set 'true' OJB try to build a
 63  
  *          sequence name automatic if none found in field-descriptor
 64  
  *          and set this generated name as <code>sequence-name</code>
 65  
  *          in field-descriptor.
 66  
  *          <br/>
 67  
  *          If set 'false' OJB throws an exception
 68  
  *          if none sequence name was found in field-descriptor, ditto
 69  
  *          OJB does NOT try to create a database sequence entry when
 70  
  *          for given sequence name no database sequence could be found.
 71  
  *    </td>
 72  
  * </tr>
 73  
  * </table>
 74  
  *
 75  
  *
 76  
  * <br/>
 77  
  * <p>
 78  
  * <b>Limitations:</b>
 79  
  * <ul>
 80  
  *        <li>none</li>
 81  
  * </ul>
 82  
  * </p>
 83  
  * <br/>
 84  
  * <br/>
 85  
  *
 86  
  * @author Edson Carlos Ericksson Richter
 87  
  * @author Rajeev Kaul
 88  
  * @author Thomas Mahler
 89  
  * @author Armin Waibel
 90  
  * @version $Id: SequenceManagerNextValImpl.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
 91  
  */
 92  
 public class SequenceManagerNextValImpl extends AbstractSequenceManager
 93  
 {
 94  
     private Logger log = LoggerFactory.getLogger(SequenceManagerNextValImpl.class);
 95  
 
 96  
     /**
 97  
      *
 98  
      */
 99  
     public SequenceManagerNextValImpl(PersistenceBroker broker)
 100  
     {
 101  
         super(broker);
 102  
     }
 103  
 
 104  
     /**
 105  
      * returns a unique int value for class clazz and field fieldName.
 106  
      * the returned number is unique accross all tables in the extent of clazz.
 107  
      */
 108  
     protected int getUniqueId(FieldDescriptor field) throws SequenceManagerException
 109  
     {
 110  
             return (int) getUniqueLong(field);
 111  
     }
 112  
 
 113  
 
 114  
     /**
 115  
      * returns a unique long value for class clazz and field fieldName.
 116  
      * the returned number is unique accross all tables in the extent of clazz.
 117  
      */
 118  
     protected long getUniqueLong(FieldDescriptor field) throws SequenceManagerException
 119  
     {
 120  
         long result;
 121  
         // lookup sequence name
 122  
         String sequenceName = calculateSequenceName(field);
 123  
         try
 124  
         {
 125  
             result = buildNextSequence(field.getClassDescriptor(), sequenceName);
 126  
         }
 127  
         catch (Throwable e)
 128  
         {
 129  
             // maybe the sequence was not created
 130  
             try
 131  
             {
 132  
                 log.info("Create DB sequence key '"+sequenceName+"'");
 133  
                 createSequence(field.getClassDescriptor(), sequenceName);
 134  
             }
 135  
             catch (Exception e1)
 136  
             {
 137  
                 throw new SequenceManagerException(
 138  
                         SystemUtils.LINE_SEPARATOR +
 139  
                         "Could not grab next id, failed with " + SystemUtils.LINE_SEPARATOR +
 140  
                         e.getMessage() + SystemUtils.LINE_SEPARATOR +
 141  
                         "Creation of new sequence failed with " +
 142  
                         SystemUtils.LINE_SEPARATOR + e1.getMessage() + SystemUtils.LINE_SEPARATOR
 143  
                         , e1);
 144  
             }
 145  
             try
 146  
             {
 147  
                 result = buildNextSequence(field.getClassDescriptor(), sequenceName);
 148  
             }
 149  
             catch (Throwable e1)
 150  
             {
 151  
                 throw new SequenceManagerException("Could not grab next id, sequence seems to exist", e);
 152  
             }
 153  
         }
 154  
         return result;
 155  
     }
 156  
 
 157  
     protected long buildNextSequence(ClassDescriptor cld, String sequenceName) throws Exception
 158  
     {
 159  
         ResultSet rs = null;
 160  
         PreparedStatement stmt = null;
 161  
         long result = -1;
 162  
         StatementManagerIF stmtMan = getBrokerForClass().serviceStatementManager();
 163  
         try
 164  
         {
 165  
             stmt = stmtMan.getPreparedStatement(cld, getPlatform().nextSequenceQuery(sequenceName) ,Query.NOT_SCROLLABLE, 1, false);
 166  
             rs = stmt.executeQuery();
 167  
             rs.next();
 168  
             result = rs.getLong(1);
 169  
         }
 170  
         finally
 171  
         {
 172  
             stmtMan.closeResources(stmt, rs);
 173  
         }
 174  
         return result;
 175  
     }
 176  
 
 177  
     protected void createSequence(ClassDescriptor cld, String sequenceName) throws Exception
 178  
     {
 179  
         Statement stmt = null;
 180  
         StatementManagerIF stmtMan = getBrokerForClass().serviceStatementManager();
 181  
 // arminw: never try to remove existing sequences, because this may lead in unexpected behaviour
 182  
 // if the reason for the create call isn't a missing sequence (e.g. network problems)  
 183  
 //        try
 184  
 //        {
 185  
 //            stmt = stmtMan.getGenericStatement(cld, Query.NOT_SCROLLABLE);
 186  
 //            stmt.execute(getPlatform().dropSequenceQuery(sequenceName));
 187  
 //        }
 188  
 //        catch (Exception ignore)
 189  
 //        {
 190  
 //            // ignore it
 191  
 //        }
 192  
 //        finally
 193  
 //        {
 194  
 //            try
 195  
 //            {
 196  
 //                stmtMan.closeResources(stmt, null);
 197  
 //            }
 198  
 //            catch (Exception ignore)
 199  
 //            {
 200  
 //                // ignore it
 201  
 //            }
 202  
 //        }
 203  
 
 204  
         try
 205  
         {
 206  
             stmt = stmtMan.getGenericStatement(cld, Query.NOT_SCROLLABLE);
 207  
             stmt.execute(getPlatform().createSequenceQuery(sequenceName, getConfigurationProperties()));
 208  
         }
 209  
         finally
 210  
         {
 211  
             try
 212  
             {
 213  
                 stmtMan.closeResources(stmt, null);
 214  
             }
 215  
             catch (Exception e)
 216  
             {
 217  
                 e.printStackTrace();
 218  
             }
 219  
         }
 220  
     }
 221  
 }