OPENJPA-2068: Optimized calendar creation.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1212503 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2011-12-09 16:30:58 +00:00
parent 8d2b795b34
commit e24439984b
6 changed files with 86 additions and 25 deletions

View File

@ -24,6 +24,7 @@ import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.sql.Result;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.jdbc.sql.SelectExecutor;
import org.apache.openjpa.util.ProxyCalendar;
/**
* Object provider implementation wrapped around a {@link Select}.
@ -56,6 +57,10 @@ public class InstanceResultObjectProvider
ClassMapping mapping = res.getBaseMapping();
if (mapping == null)
mapping = _mapping;
return res.load(mapping, getStore(), getFetchConfiguration());
Object ret = res.load(mapping, getStore(), getFetchConfiguration());
if (ret != null && ret instanceof ProxyCalendar) {
ret = ((ProxyCalendar) ret).copy(ret);
}
return ret;
}
}

View File

@ -44,6 +44,7 @@ import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.DateFormatSymbols;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@ -51,6 +52,7 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -59,6 +61,8 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.spi.TimeZoneNameProvider;
import javax.sql.DataSource;
@ -118,6 +122,7 @@ import org.apache.openjpa.util.ObjectExistsException;
import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OptimisticException;
import org.apache.openjpa.util.ProxyManager;
import org.apache.openjpa.util.QueryException;
import org.apache.openjpa.util.ReferentialIntegrityException;
import org.apache.openjpa.util.Serialization;
@ -421,6 +426,8 @@ public class DBDictionary
public final Map<Integer,Set<String>> sqlStateCodes =
new HashMap<Integer, Set<String>>();
protected ProxyManager _proxyManager;
public DBDictionary() {
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
"BIGINT", "BIT", "BLOB", "CLOB", "DATE", "DECIMAL", "DISTINCT",
@ -692,17 +699,22 @@ public class DBDictionary
* Convert the specified column of the SQL ResultSet to the proper
* java type. Converts the date from a {@link Timestamp} by default.
*/
public Calendar getCalendar(ResultSet rs, int column)
throws SQLException {
public Calendar getCalendar(ResultSet rs, int column) throws SQLException {
Date d = getDate(rs, column);
if (d == null)
return null;
Calendar cal = Calendar.getInstance();
Calendar cal = (Calendar) getProxyManager().newCalendarProxy(GregorianCalendar.class, null);
cal.setTime(d);
return cal;
}
private ProxyManager getProxyManager() {
if (_proxyManager == null) {
_proxyManager = conf.getProxyManagerInstance();
}
return _proxyManager;
}
/**
* Convert the specified column of the SQL ResultSet to the proper
* java type.
@ -5540,5 +5552,4 @@ public class DBDictionary
public String getIdentityColumnName() {
return null;
}
}

View File

@ -18,6 +18,10 @@
*/
package org.apache.openjpa.kernel;
import java.util.Calendar;
import org.apache.openjpa.util.ProxyCalendar;
/**
* Packs result by delegation to a ResultShape.
@ -43,6 +47,18 @@ public class ResultShapePacker extends ResultPacker {
@Override
public Object pack(Object[] values) {
// Check for proxied calenders and cleanup if any are found.
if (_types != null) {
for (Class<?> t : _types) {
if (t.equals(Calendar.class)) {
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof ProxyCalendar) {
values[i] = ((ProxyCalendar) values[i]).copy((ProxyCalendar) values[i]);
}
}
}
}
}
if (_shape == null)
return super.pack(values);
return _shape.pack(values, _types, _aliases);

View File

@ -28,6 +28,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.TimeZone;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.enhance.PersistenceCapable;
@ -77,31 +78,34 @@ class SingleFieldManager extends TransferFieldManager implements Serializable {
case JavaTypes.DATE:
if (objval == null)
return false;
proxy = checkProxy();
proxy = checkProxy(fmd);
if (proxy == null) {
proxy = (Proxy) _sm.newFieldProxy(field);
((Date) proxy).setTime(((Date) objval).getTime());
if (proxy instanceof Timestamp
&& objval instanceof Timestamp)
((Timestamp) proxy).setNanos(((Timestamp) objval).
getNanos());
if (proxy instanceof Timestamp && objval instanceof Timestamp)
((Timestamp) proxy).setNanos(((Timestamp) objval).getNanos());
ret = true;
}
break;
case JavaTypes.CALENDAR:
if (objval == null)
return false;
proxy = checkProxy();
proxy = checkProxy(fmd);
if (proxy == null) {
proxy = (Proxy) _sm.newFieldProxy(field);
((Calendar) proxy).setTime(((Calendar) objval).getTime());
ret = true;
} else {
Object init = fmd.getInitializer();
if (init != null && init instanceof TimeZone) {
((Calendar) proxy).setTimeZone((TimeZone)init);
}
}
break;
case JavaTypes.COLLECTION:
if (objval == null && !replaceNull)
return false;
proxy = checkProxy();
proxy = checkProxy(fmd);
if (proxy == null) {
proxy = (Proxy) _sm.newFieldProxy(field);
if (objval != null)
@ -112,7 +116,7 @@ class SingleFieldManager extends TransferFieldManager implements Serializable {
case JavaTypes.MAP:
if (objval == null && !replaceNull)
return false;
proxy = checkProxy();
proxy = checkProxy(fmd);
if (proxy == null) {
proxy = (Proxy) _sm.newFieldProxy(field);
if (objval != null)
@ -123,7 +127,7 @@ class SingleFieldManager extends TransferFieldManager implements Serializable {
case JavaTypes.OBJECT:
if (objval == null)
return false;
proxy = checkProxy();
proxy = checkProxy(fmd);
if (proxy == null) {
proxy = getProxyManager().newCustomProxy(objval,
_sm.getBroker().getConfiguration().
@ -152,13 +156,16 @@ class SingleFieldManager extends TransferFieldManager implements Serializable {
/**
* If the current field is a usable proxy, return it; else return null.
*/
private Proxy checkProxy() {
private Proxy checkProxy(FieldMetaData fmd) {
if (!(objval instanceof Proxy))
return null;
Proxy proxy = (Proxy) objval;
if (proxy.getOwner() == null || Proxies.isOwner(proxy, _sm, field))
return proxy;
if (proxy.getOwner() == null || Proxies.isOwner(proxy, _sm, field)) {
if(fmd.getProxyType().isAssignableFrom(proxy.getClass())){
return proxy;
}
}
return null;
}

View File

@ -20,14 +20,13 @@ package org.apache.openjpa.jdbc.meta;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.simple.TemporalFieldTypes;
import org.apache.openjpa.persistence.test.SingleEMTestCase;
import org.apache.openjpa.util.ProxyCalendar;
public class TestCalendarField extends SingleEMTestCase {
@ -54,4 +53,24 @@ public class TestCalendarField extends SingleEMTestCase {
tft = find(TemporalFieldTypes.class).get(0);
assertEquals(tz, tft.getCalendarTimeZoneField().getTimeZone());
}
public void testCalendarQuery() throws Exception {
persist(new TemporalFieldTypes());
persist(new TemporalFieldTypes());
persist(new TemporalFieldTypes());
em.clear();
Calendar cal =
em.createQuery("SELECT t.calendarTimeZoneField FROM TemporalFieldTypes t WHERE 1=1", Calendar.class)
.setMaxResults(1).getSingleResult();
assertFalse(cal instanceof ProxyCalendar);
List<Calendar> cals =
em.createQuery("SELECT t.calendarTimeZoneField FROM TemporalFieldTypes t WHERE 1=1", Calendar.class)
.setMaxResults(3).getResultList();
for (Calendar c : cals) {
assertFalse(c instanceof ProxyCalendar);
}
}
}

View File

@ -40,7 +40,7 @@ public class LRSEntity {
@ManyToMany
@OrderBy("name ASC")
@LRS
private Collection<BasicEntity> lrsList = new ArrayList<BasicEntity>();
private Collection<BasicEntity> lrsList;
public long getId() {
return id;
@ -55,6 +55,9 @@ public class LRSEntity {
}
public Collection<BasicEntity> getLRSList() {
if (lrsList == null) {
lrsList = new ArrayList<BasicEntity>();
}
return lrsList;
}
}