diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
index 016d53d97..57232a4bc 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
@@ -410,14 +410,13 @@ public class EmbedFieldStrategy
//### we selected the embedded object fields and load the object
//### immediately; this will be inefficient when the embedded object
//### was not selected after all
-
StoreContext ctx = store.getContext();
OpenJPAStateManager em = ctx.embed(null, null, sm, field);
sm.storeObject(field.getIndex(), em.getManagedInstance());
FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
Object eres, processed;
- boolean loaded = false;
+ boolean needsLoad = false;
for (int i = 0; i < fields.length; i++) {
eres = res.getEager(fields[i]);
res.startDataRequest(fields[i]);
@@ -429,18 +428,24 @@ public class EmbedFieldStrategy
fields[i].loadEagerParallel(em, store, fetch, eres);
if (processed != eres)
res.putEager(fields[i], processed);
- } else
+ } else {
fields[i].load(em, store, fetch, res);
- loaded |= em.getLoaded().get(i);
+ }
+ needsLoad = needsLoad || (!em.getLoaded().get(i) &&
+ fetch.requiresFetch(fields[i])
+ == FetchConfiguration.FETCH_LOAD);
} finally {
res.endDataRequest();
}
}
- // after loading everything from result, load the rest of the
- // configured fields
- if (loaded)
- em.load(fetch);
+ // After loading everything from result, load the rest of the
+ // configured fields if anything is missing.
+ if (needsLoad &&
+ fetch.requiresFetch(field.getFieldMetaData()) ==
+ JDBCFetchConfiguration.FETCH_LOAD) {
+ em.load(fetch);
+ }
}
/**
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
index 71ec7305c..a36c1ed2d 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
@@ -157,7 +157,8 @@ public class HandlerFieldStrategy
if (sm != null && sm.getIntermediate(field.getIndex()) != null)
return -1;
- if (sel.isDistinct() && _lob && !field.isPrimaryKey())
+ if (_lob && !field.isPrimaryKey() && (sel.isDistinct() ||
+ eagerMode == JDBCFetchConfiguration.EAGER_NONE))
return -1;
sel.select(_cols, field.join(sel));
return 1;
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java
index fa6891f50..a807f847d 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java
@@ -162,15 +162,13 @@ public class DataSourceFactory {
decorators.addAll(decs);
}
- if (jdbcLog.isTraceEnabled() || sqlLog.isTraceEnabled()) {
- // logging decorator
- LoggingConnectionDecorator lcd =
- new LoggingConnectionDecorator();
- Configurations.configureInstance(lcd, conf, opts);
- lcd.getLogs().setJDBCLog(jdbcLog);
- lcd.getLogs().setSQLLog(sqlLog);
- decorators.add(lcd);
- }
+ // logging decorator
+ LoggingConnectionDecorator lcd =
+ new LoggingConnectionDecorator();
+ Configurations.configureInstance(lcd, conf, opts);
+ lcd.getLogs().setJDBCLog(jdbcLog);
+ lcd.getLogs().setSQLLog(sqlLog);
+ decorators.add(lcd);
dds.addDecorators(decorators);
return dds;
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
index 358bda129..9b01fc66f 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.sql;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@@ -51,7 +53,7 @@ public class MySQLDictionary
/**
* Whether the driver automatically deserializes blobs.
*/
- public boolean driverDeserializesBlobs = true;
+ public boolean driverDeserializesBlobs = false;
/**
* Whether to inline multi-table bulk-delete operations into MySQL's
@@ -70,11 +72,9 @@ public class MySQLDictionary
supportsDeferredConstraints = false;
constraintNameMode = CONS_NAME_MID;
supportsMultipleNontransactionalResultSets = false;
- supportsSubselect = false; // old versions
requiresAliasForSubselect = true; // new versions
supportsSelectStartIndex = true;
supportsSelectEndIndex = true;
- allowsAliasInBulkClause = false;
concatenateFunction = "CONCAT({0},{1})";
@@ -112,6 +112,68 @@ public class MySQLDictionary
"ZEROFILL" }));
}
+ public void connectedConfiguration(Connection conn) throws SQLException {
+ super.connectedConfiguration(conn);
+
+ DatabaseMetaData metaData = conn.getMetaData();
+ // The product version looks like 4.1.3-nt
+ String productVersion = metaData.getDatabaseProductVersion();
+ // The driver version looks like mysql-connector-java-3.1.11 (...)
+ String driverVersion = metaData.getDriverVersion();
+
+ try {
+ int[] versions = getMajorMinorVersions(productVersion);
+ int maj = versions[0];
+ int min = versions[1];
+ if (maj < 4 || (maj == 4 && min < 1)) {
+ supportsSubselect = false;
+ allowsAliasInBulkClause = false;
+ }
+
+ versions = getMajorMinorVersions(driverVersion);
+ maj = versions[0];
+ if (maj < 5) {
+ driverDeserializesBlobs = true;
+ }
+ } catch (IllegalArgumentException e) {
+ // we don't understand the version format.
+ // That is ok. We just take the default values.
+ }
+ }
+
+ private static int[] getMajorMinorVersions(String versionStr)
+ throws IllegalArgumentException {
+ int beginIndex = 0;
+ int endIndex = 0;
+
+ versionStr = versionStr.trim();
+ char[] charArr = versionStr.toCharArray();
+ for (int i = 0; i < charArr.length; i++) {
+ if (Character.isDigit(charArr[i])) {
+ beginIndex = i;
+ break;
+ }
+ }
+
+ for (int i = beginIndex+1; i < charArr.length; i++) {
+ if (charArr[i] != '.' && !Character.isDigit(charArr[i])) {
+ endIndex = i;
+ break;
+ }
+ }
+
+ if (endIndex < beginIndex)
+ throw new IllegalArgumentException();
+
+ String[] arr = versionStr.substring(beginIndex, endIndex).split("\\.");
+ if (arr.length < 2)
+ throw new IllegalArgumentException();
+
+ int maj = Integer.parseInt(arr[0]);
+ int min = Integer.parseInt(arr[1]);
+ return new int[]{maj, min};
+ }
+
public String[] getCreateTableSQL(Table table) {
String[] sql = super.getCreateTableSQL(table);
if (!StringUtils.isEmpty(tableType))
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
index 5bf7969bc..467efdbfd 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
@@ -1124,9 +1124,11 @@ public class FieldMetaData
//set "isUsedInOrderBy" to the field
ClassMetaData elemCls = getElement()
.getDeclaredTypeMetaData();
- FieldMetaData fmd = elemCls.getDeclaredField(decs[i]);
- if (fmd != null)
- fmd.setUsedInOrderBy(true);
+ if (elemCls != null) {
+ FieldMetaData fmd = elemCls.getDeclaredField(decs[i]);
+ if (fmd != null)
+ fmd.setUsedInOrderBy(true);
+ }
}
_orders = orders;
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceComparator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceComparator.java
index 8e9679f4c..12e185627 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceComparator.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceComparator.java
@@ -30,7 +30,7 @@ import java.util.Comparator;
public class InheritanceComparator
implements Comparator, Serializable {
- private Class _base = null;
+ private Class _base = Object.class;
/**
* Set the least-derived type possible; defaults to null
.
@@ -92,8 +92,6 @@ public class InheritanceComparator
private int levels(Class to) {
if (to.isInterface())
return to.getInterfaces().length;
- if (_base == null)
- return 0;
for (int i = 0; to != null; i++, to = to.getSuperclass())
if (to == _base)
return i;
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceOrderedMetaDataList.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceOrderedMetaDataList.java
new file mode 100644
index 000000000..79376fb71
--- /dev/null
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InheritanceOrderedMetaDataList.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.meta;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.io.Serializable;
+
+public class InheritanceOrderedMetaDataList
+ implements Serializable {
+
+ private MetaDataInheritanceComparator _comp
+ = new MetaDataInheritanceComparator();
+ private LinkedList buffer = new LinkedList();
+
+ public boolean add(ClassMetaData meta) {
+ if (meta == null || buffer.contains(meta))
+ return false;
+ for (ListIterator itr = buffer.listIterator();
+ itr.hasNext();) {
+ int ord = _comp.compare(meta, itr.next());
+ if (ord > 0)
+ continue;
+ if (ord == 0)
+ return false;
+ itr.previous();
+ itr.add(meta);
+ return true;
+ }
+ buffer.add(meta);
+ return true;
+ }
+
+ public boolean remove(ClassMetaData meta) {
+ return buffer.remove(meta);
+ }
+
+ public ClassMetaData peek() {
+ return buffer.peek();
+ }
+
+ public int size() {
+ return buffer.size();
+ }
+
+ public Iterator iterator() {
+ return buffer.iterator();
+ }
+
+ public boolean isEmpty() {
+ return buffer.isEmpty();
+ }
+
+ public void clear() {
+ buffer.clear();
+ }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
index 1a5aea3b5..1b5845769 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
@@ -31,7 +31,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang.StringUtils;
@@ -137,10 +136,10 @@ public class MetaDataRepository
private final Collection _registered = new HashSet();
// set of metadatas we're in the process of resolving
- private final SortedSet _resolving = new TreeSet
- (new MetaDataInheritanceComparator());
- private final SortedSet _mapping = new TreeSet
- (new MetaDataInheritanceComparator());
+ private final InheritanceOrderedMetaDataList _resolving =
+ new InheritanceOrderedMetaDataList();
+ private final InheritanceOrderedMetaDataList _mapping =
+ new InheritanceOrderedMetaDataList();
private final List _errs = new LinkedList();
// system listeners
@@ -574,7 +573,6 @@ public class MetaDataRepository
* if we're still in the process of resolving other metadatas.
*/
private List resolveMeta(ClassMetaData meta) {
- setBaseIfNecessary(meta);
if (meta.getPCSuperclass() == null) {
// set superclass
Class sup = meta.getDescribedType().getSuperclass();
@@ -618,27 +616,6 @@ public class MetaDataRepository
return processBuffer(meta, _resolving, MODE_META);
}
- private void setBaseIfNecessary(ClassMetaData meta) {
- if (_resolving == null)
- return;
-
- InheritanceComparator comp =
- (InheritanceComparator) _resolving.comparator();
- if (meta.getPCSuperclass() == null) {
- Class sup = meta.getDescribedType().getSuperclass();
- Class pBase = null;
- while (sup != null && sup != Object.class) {
- pBase = sup;
- sup = sup.getSuperclass();
- }
- if (pBase != null && !pBase.equals(comp.getBase())) {
- // setBase() can be called because getMetaData() is
- // syncronized
- comp.setBase(pBase);
- }
- }
- }
-
/**
* Load mapping information for the given metadata.
*/
@@ -719,7 +696,8 @@ public class MetaDataRepository
/**
* Process the given metadata and the associated buffer.
*/
- private List processBuffer(ClassMetaData meta, SortedSet buffer, int mode) {
+ private List processBuffer(ClassMetaData meta,
+ InheritanceOrderedMetaDataList buffer, int mode) {
// if we're already processing a metadata, just buffer this one; when
// the initial metadata finishes processing, we traverse the buffer
// and process all the others that were introduced during reentrant
@@ -734,7 +712,7 @@ public class MetaDataRepository
ClassMetaData buffered;
List processed = new ArrayList(5);
while (!buffer.isEmpty()) {
- buffered = (ClassMetaData) buffer.first();
+ buffered = buffer.peek();
try {
buffered.resolve(mode);
processed.add(buffered);
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
index 257e66605..c93377fc4 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/meta/TestMetaDataInheritanceComparator.java
@@ -25,10 +25,6 @@ import org.apache.openjpa.persistence.JPAFacadeHelper;
public class TestMetaDataInheritanceComparator extends PersistenceTestCase {
- public void testInheritanceComparatorWithoutBase() {
- inheritanceComparatorHelper(false);
- }
-
public void testInheritanceComparatorWithBase() {
inheritanceComparatorHelper(true);
}
@@ -47,10 +43,6 @@ public class TestMetaDataInheritanceComparator extends PersistenceTestCase {
assertTrue(comp.compare(AbstractThing.class, C.class) < 0);
}
- public void testMetaDataInheritanceComparatorWithoutBase() {
- metaDataInheritanceComparatorHelper(false);
- }
-
public void testMetaDataInheritanceComparatorWithBase() {
metaDataInheritanceComparatorHelper(true);
}