KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > repository > rdbms > RdbmsIdProvider


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, is permitted
5  * provided that the following conditions are met:
6  * - Redistributions of source code must retain the above copyright notice, this list of conditions
7  * and the following disclaimer.
8  * - Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * - All advertising materials mentioning features or use of this software must display the
12  * following acknowledgment: "This product includes Djeneric."
13  * - Products derived from this software may not be called "Djeneric" nor may
14  * "Djeneric" appear in their names without prior written permission of Genimen BV.
15  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
16  * product includes Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.repository.rdbms;
31
32 import java.sql.ResultSet JavaDoc;
33 import java.sql.SQLException JavaDoc;
34 import java.util.Stack JavaDoc;
35
36 import com.genimen.djeneric.repository.DjIdProvider;
37 import com.genimen.djeneric.repository.DjSession;
38 import com.genimen.djeneric.repository.exceptions.DjenericException;
39
40 public class RdbmsIdProvider extends DjIdProvider
41 {
42   Stack JavaDoc _cache = new Stack JavaDoc();
43
44   public RdbmsIdProvider()
45   {
46     setSequenceName(RdbmsPersistenceManager.POLYMORPH_TABLE);
47   }
48
49   public RdbmsIdProvider(int cacheSize)
50   {
51     super(cacheSize);
52   }
53
54   // A new session ins created to be able to commit here without affecting the calling session.
55
public long getNextId(DjSession forSession) throws DjenericException
56   {
57     if (!_cache.isEmpty())
58     {
59       Long JavaDoc val = (Long JavaDoc) _cache.pop();
60       return val.longValue();
61     }
62
63     try
64     {
65       RdbmsSession session = (RdbmsSession) forSession.getPersistenceManager().createSession();
66       try
67       {
68         // First update the counter (and keep it locked)
69
SqlStatement s = session.getInternalSqlStatement("update " + RdbmsPersistenceManager.INTERNAL_IDS_TABLE
70                                                          + " set next_value = next_value + :incr"
71                                                          + " where name = :seqName");
72         s.setInt("incr", getCacheSize() + 1);
73         s.setString("seqName", getSequenceName());
74         int recsHit = s.executeUpdate();
75         s.close();
76
77         if (recsHit == 0)
78         {
79           // First call, create the entry in the sequence table
80
s = session.getInternalSqlStatement("insert into " + RdbmsPersistenceManager.INTERNAL_IDS_TABLE
81                                               + "(name, next_value) values(:seqName, " + (getCacheSize() + 2) + ")");
82           s.setString("seqName", getSequenceName());
83           s.executeUpdate();
84         }
85
86         // Now retrieve the counter (that is locked by us) so ONLY WE get this number now!
87
s = session
88             .getInternalSqlStatement("select next_value " + "from " + RdbmsPersistenceManager.INTERNAL_IDS_TABLE
89                                      + " " + "where name = :name ");
90         s.setString("name", getSequenceName());
91         ResultSet JavaDoc rs = s.executeQuery();
92         long id;
93         if (rs.next())
94         {
95           id = rs.getLong("next_value") - 1;
96         }
97         else throw new DjenericException("Internal error, could not get next object id");
98
99         rs.close();
100         s.close();
101         session.commit();
102
103         long lastId = id;
104         for (int i = 0; i < getCacheSize(); i++)
105         {
106           _cache.push(new Long JavaDoc(lastId - i));
107         }
108         return id - getCacheSize();
109       }
110       finally
111       {
112         session.close();
113       }
114     }
115     catch (SQLException JavaDoc x)
116     {
117       throw new DjenericException(x);
118     }
119   }
120 }
Popular Tags