KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > metadata > fieldaccess > AnonymousPersistentField


1 package org.apache.ojb.broker.metadata.fieldaccess;
2
3 /* Copyright 2003-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.util.Map JavaDoc;
19
20 import org.apache.commons.collections.map.ReferenceIdentityMap;
21 import org.apache.ojb.broker.metadata.MetadataException;
22
23 /**
24  * This class handle an anonymous persistent fiels for 1-1 association,
25  * and ojbConcreteClass
26  * @author Houar TINE
27  * @version $Id: AnonymousPersistentField.java,v 1.13.2.2 2005/12/21 22:26:41 tomdz Exp $
28  */

29 public class AnonymousPersistentField implements PersistentField
30 {
31     private static final long serialVersionUID = 3989863424358352941L;
32
33     private transient Map JavaDoc fkCache;
34     private String JavaDoc fieldname;
35
36     public AnonymousPersistentField(String JavaDoc fieldname)
37     {
38         this.fieldname = fieldname;
39     }
40
41     public synchronized void set(Object JavaDoc obj, Object JavaDoc value) throws MetadataException
42     {
43         putToFieldCache(obj, value);
44     }
45
46     public synchronized Object JavaDoc get(Object JavaDoc anObject) throws MetadataException
47     {
48         return getFromFieldCache(anObject);
49     }
50
51 /*
52     Use ReferenceIdentityMap (with weak key and hard value setting) instead of
53     WeakHashMap to hold anonymous field values. Here is an snip of the mail from Andy Malakov:
54     <snip>
55         I found that usage of database identity in Java produces quite interesting problem in OJB:
56         In my application all persistent Java objects use database identity instead of Java reference identity
57         (i.e. Persistable.equals() is redefined so that two persistent objects are the same if they have the same
58         primary key and top-level class).
59
60         In OJB, for each field declared in repository there is dedicated instance of AnonymousPersistentField that stores
61         object-to-field-value mapping in WeakHashMap (in fkCache attribute). Despite usage of cache
62         (ObjectCachePerBrokerImpl in my case) it is possible that identical DB objects will end up as different
63         Java objects during retrieval of complex objects.
64
65         Now imagine what happens when two identical instances are retrieved:
66         1)
67         When first instance is retrieved it stores its foreign keys in AnonymousPersistentField.fkCache under instance's
68         identity. (happens in RowReaderDefaultImpl.buildWithReflection())
69         2)
70         When second object is retrieved and stored in fkCache, first instance is probably still cached
71         [WeakHashMap entries are cleaned up only during GC]. Since keys are identical WeakHashMap only updates entry
72         value and DOES NOT update entry key.
73         3)
74         If Full GC happens after that moment it will dispose fcCache entry if the FIRST reference becomes
75         soft-referenced only.
76     </snip>
77 */

78     protected void putToFieldCache(Object JavaDoc key, Object JavaDoc value)
79     {
80         if (key != null)
81         {
82             if (fkCache == null)
83             {
84                 fkCache = new ReferenceIdentityMap (ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD, true);
85             }
86             if (value != null)
87                  fkCache.put(key, value);
88              else
89                  fkCache.remove (key);
90         }
91     }
92
93     protected Object JavaDoc getFromFieldCache(Object JavaDoc key)
94     {
95         return (key != null && fkCache != null) ? fkCache.get(key) : null;
96     }
97
98     /**
99      * Always returns <tt>null</tt>.
100      * @see PersistentField#getDeclaringClass()
101      */

102     public Class JavaDoc getDeclaringClass()
103     {
104         return null;
105     }
106
107     /**
108      * @see PersistentField#getName()
109      */

110     public String JavaDoc getName()
111     {
112         return fieldname;
113     }
114
115     /**
116      * Always returns <tt>null</tt>.
117      * @see PersistentField#getType()
118      */

119     public Class JavaDoc getType()
120     {
121         return null;
122     }
123
124     /**
125      * Returns <tt>false</tt>.
126      * @see PersistentField#usesAccessorsAndMutators()
127      */

128     public boolean usesAccessorsAndMutators()
129     {
130         return false;
131     }
132 }
133
Popular Tags