You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by jr...@apache.org on 2009/06/12 04:40:14 UTC
svn commit: r783966 - in /openjpa/trunk:
openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/
openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attr...
Author: jrbauer
Date: Fri Jun 12 02:40:14 2009
New Revision: 783966
URL: http://svn.apache.org/viewvc?rev=783966&view=rev
Log:
OPENJPA-1135 Apply overrides to deferred embeddable attributes
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java (with props)
Modified:
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/TestAttrOverridesXml.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java Fri Jun 12 02:40:14 2009
@@ -525,6 +525,7 @@
if (_log != null && _log.isTraceEnabled())
_log.trace(_loc.get("end-parse", getSourceName()));
_results = new ArrayList(_curResults);
+ clearDeferredMetaData();
}
/**
@@ -679,4 +680,7 @@
e.initCause(cause);
return e;
}
+
+ protected void clearDeferredMetaData() {
+ }
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java Fri Jun 12 02:40:14 2009
@@ -1297,9 +1297,14 @@
parseColumns(efm, attr.column());
}
}
-
+
public static FieldMapping getEmbeddedFieldMapping(FieldMapping fm,
- String attrName) {
+ String attrName) {
+ return getEmbeddedFieldMapping(fm, attrName, true);
+ }
+
+ public static FieldMapping getEmbeddedFieldMapping(FieldMapping fm,
+ String attrName, boolean mustExist) {
ClassMapping embed = null;
boolean isKey = false;
boolean isValue = false;
@@ -1323,31 +1328,83 @@
throw new MetaDataException(_loc.get("embed-override-name",
fm, attrName));
if (isKey)
- embed = getEmbeddedMapping(fm.getKeyMapping());
+ embed = getEmbeddedMapping(fm.getKeyMapping(), mustExist);
else if (isValue)
- embed = getEmbeddedMapping(fm.getElementMapping());
+ embed = getEmbeddedMapping(fm.getElementMapping(),
+ mustExist);
break;
default: // an embeddable
if (isKey || isValue)
throw new MetaDataException(_loc.get("embed-override-name",
fm, attrName));
- embed = getEmbeddedMapping(fm.getValueMapping());
+ embed = getEmbeddedMapping(fm.getValueMapping(), mustExist);
break;
}
- if (embed == null)
- throw new MetaDataException(_loc.get("not-embedded", fm));
+ if (embed == null) {
+ if (mustExist)
+ throw new MetaDataException(_loc.get("not-embedded", fm));
+ return null;
+ }
return getAttributeOverrideField(attrName, fm, embed);
}
-
- public static ClassMapping getEmbeddedMapping(ValueMapping val) {
+
+ public static Class<?> getEmbeddedClassType(FieldMapping fm,
+ String attrName) {
+ ValueMapping embed = null;
+ boolean isKey = false;
+ boolean isValue = false;
+ if (attrName != null && attrName.startsWith("key."))
+ isKey = true;
+ else if (attrName != null && attrName.startsWith("value."))
+ isValue = true;
+ if (isKey || isValue)
+ attrName = attrName.substring(attrName.indexOf(".")+1);
+
+ int typeCode = fm.getValue().getDeclaredTypeCode();
+ switch (typeCode) {
+ case JavaTypes.COLLECTION : // a collection of embeddables
+ if (isKey || isValue)
+ throw new MetaDataException(_loc.get("embed-override-name",
+ fm, attrName));
+ embed = fm.getElementMapping();
+ break;
+ case JavaTypes.MAP: // a map
+ if (!isKey && !isValue)
+ throw new MetaDataException(_loc.get("embed-override-name",
+ fm, attrName));
+ if (isKey)
+ embed = fm.getKeyMapping();
+ else if (isValue)
+ embed = fm.getElementMapping();
+ break;
+ default: // an embeddable
+ if (isKey || isValue)
+ throw new MetaDataException(_loc.get("embed-override-name",
+ fm, attrName));
+ embed = fm.getValueMapping();
+ break;
+ }
+
+ if (embed == null) {
+ throw new MetaDataException(_loc.get("not-embedded", fm));
+ }
+ return embed.getDeclaredType();
+ }
+
+ public static ClassMapping getEmbeddedMapping(ValueMapping val, boolean
+ createNew) {
ClassMapping embed = val.getEmbeddedMapping();
- if (embed != null)
+ if (embed != null || !createNew)
return embed;
-
+
val.addEmbeddedMetaData();
return val.getEmbeddedMapping();
+ }
+
+ public static ClassMapping getEmbeddedMapping(ValueMapping val) {
+ return getEmbeddedMapping(val, true);
}
public static FieldMapping getAttributeOverrideField(String attrName,
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java Fri Jun 12 02:40:14 2009
@@ -56,8 +56,11 @@
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataContext;
+import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.persistence.XMLPersistenceMetaDataParser;
import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.MetaDataException;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
@@ -123,6 +126,10 @@
private Column _discCol;
private int _resultIdx = 0;
+ private final Map<Class<?>, ArrayList<DeferredEmbeddableOverrides>>
+ _deferredMappings = new HashMap<Class<?>,
+ ArrayList<DeferredEmbeddableOverrides>>();
+
/**
* Constructor; supply configuration.
*/
@@ -655,9 +662,13 @@
* Set unique for field.
*/
private void setUnique(FieldMapping fm) {
- if (_unique.size() == 2) // i.e. TRUE & FALSE
+ setUnique(fm, _unique);
+ }
+
+ private void setUnique(FieldMapping fm, EnumSet<UniqueFlag> unique) {
+ if (unique.size() == 2) // i.e. TRUE & FALSE
getLog().warn(_loc.get("inconsist-col-attrs", fm));
- else if (_unique.contains(UniqueFlag.TRUE))
+ else if (unique.contains(UniqueFlag.TRUE))
fm.getValueInfo().setUnique(new Unique());
}
@@ -690,9 +701,23 @@
FieldMapping fm = null;
if (elem instanceof ClassMapping)
fm = getAttributeOverride((ClassMapping) elem);
- else
- fm = getAttributeOverrideForEmbeddable((FieldMapping) elem);
- if (_cols != null) {
+ else {
+ FieldMapping basefm = (FieldMapping) elem;
+
+ fm = getAttributeOverrideForEmbeddable(basefm, _override, false);
+ if (fm == null) {
+ DeferredEmbeddableOverrides dfm =
+ getDeferredFieldMappingInfo(
+ AnnotationPersistenceMappingParser.
+ getEmbeddedClassType(basefm, _override),
+ basefm, _override, true);
+ dfm._defCols = _cols;
+ dfm._defTable = _colTable;
+ dfm._attrName = _override;
+ dfm._unique = _unique;
+ }
+ }
+ if (fm != null && _cols != null) {
fm.getValueInfo().setColumns(_cols);
if (_colTable != null)
fm.getMappingInfo().setTableName(_colTable);
@@ -717,10 +742,11 @@
/**
* Return the proper override.
*/
- private FieldMapping getAttributeOverrideForEmbeddable(FieldMapping fm)
+ private FieldMapping getAttributeOverrideForEmbeddable(FieldMapping fm,
+ String attrName, boolean mustExist)
throws SAXException {
return AnnotationPersistenceMappingParser.getEmbeddedFieldMapping(fm,
- _override);
+ attrName, mustExist);
}
/**
@@ -747,14 +773,27 @@
Object elem = currentElement();
FieldMapping fm = null;
if (elem instanceof FieldMapping) {
- fm = (FieldMapping) elem;
- if (_override != null)
- fm = getAttributeOverrideForEmbeddable(fm);
+ fm = (FieldMapping) elem;
+ if (_override != null) {
+ FieldMapping basefm = (FieldMapping) elem;
+ fm = getAttributeOverrideForEmbeddable(basefm,
+ _override, false);
+ if (fm == null) {
+ DeferredEmbeddableOverrides dfm =
+ getDeferredFieldMappingInfo(
+ AnnotationPersistenceMappingParser.
+ getEmbeddedClassType(basefm, _override),
+ basefm, _override, true);
+ dfm._defTable = table;
+ dfm._attrName = _override;
+ }
+ }
} else if (elem instanceof ClassMapping) {
ClassMapping cm = (ClassMapping) elem;
fm = getAttributeOverride(cm);
}
- fm.getMappingInfo().setTableName(table);
+ if (fm != null)
+ fm.getMappingInfo().setTableName(table);
}
return true;
}
@@ -767,17 +806,32 @@
FieldMapping fm = null;
if (elem instanceof FieldMapping) {
fm = (FieldMapping) elem;
- if (_override != null)
- fm = getAttributeOverrideForEmbeddable(fm);
+ if (_override != null) {
+ FieldMapping basefm = (FieldMapping) elem;
+ fm = getAttributeOverrideForEmbeddable(basefm, _override,
+ false);
+ if (fm == null) {
+ DeferredEmbeddableOverrides dfm =
+ getDeferredFieldMappingInfo(
+ AnnotationPersistenceMappingParser.
+ getEmbeddedClassType(basefm, _override),
+ basefm, _override, true);
+ dfm._defCols = _cols;
+ dfm._defElemJoinCols = _joinCols;
+ dfm._attrName = _override;
+ }
+ }
} else if (elem instanceof ClassMapping){
ClassMapping cm = (ClassMapping) elem;
fm = getAttributeOverride(cm);
}
- if (_joinCols != null)
- fm.getMappingInfo().setColumns(_joinCols);
- if (_cols != null)
- fm.getElementMapping().getValueInfo().setColumns(_cols);
+ if (fm != null) {
+ if (_joinCols != null)
+ fm.getMappingInfo().setColumns(_joinCols);
+ if (_cols != null)
+ fm.getElementMapping().getValueInfo().setColumns(_cols);
+ }
clearColumnInfo();
}
@@ -845,7 +899,7 @@
// a collection of basic types
// the column is in a separate table
if (fm.isElementCollection() &&
- fm.getElementMapping().getEmbeddedMapping() == null) {
+ !fm.getElementMapping().isEmbedded()) {
List list = fm.getElementMapping().getValueInfo().getColumns();
if (list.size() == 0) {
list = new ArrayList();
@@ -1208,4 +1262,125 @@
}
return col;
}
+
+ /**
+ * Process all deferred embeddable overrides for a given class.
+ * This should only occur after the embeddable is mapped.
+ *
+ * @param embedType embeddable class
+ * @param access class level access for embeddable
+ * @throws SAXException
+ */
+ @Override
+ protected void applyDeferredEmbeddableOverrides(Class<?> cls)
+ throws SAXException {
+ ArrayList<DeferredEmbeddableOverrides> defMappings =
+ _deferredMappings.get(cls);
+ if (defMappings == null)
+ return;
+
+ for (DeferredEmbeddableOverrides defMap : defMappings) {
+ FieldMapping fm = (FieldMapping)defMap._fm;
+ if (defMap == null)
+ return;
+ fm = getAttributeOverrideForEmbeddable(fm, defMap._attrName, true);
+ // Apply column, table, and unique overrides
+ if (defMap._defCols != null) {
+ fm.getValueInfo().setColumns(defMap._defCols);
+ if (defMap._defTable != null)
+ fm.getMappingInfo().setTableName(defMap._defTable);
+ setUnique(fm, defMap._unique);
+ }
+ // Apply Join column and element join columns overrides overrides
+ if (defMap._defJoinCols != null)
+ fm.getMappingInfo().setColumns(defMap._defJoinCols);
+ if (defMap._defElemJoinCols != null)
+ fm.getElementMapping().getValueInfo().setColumns(
+ defMap._defElemJoinCols);
+ }
+ // Clean up after applying mappings
+ defMappings.clear();
+ _deferredMappings.remove(cls);
+ }
+
+ /*
+ * Defer overrides for the specified field mapping
+ */
+ private void deferEmbeddableOverrides(
+ Class cls, DeferredEmbeddableOverrides defMap) {
+ ArrayList<DeferredEmbeddableOverrides> defMappings =
+ _deferredMappings.get(cls);
+ if (defMappings == null) {
+ defMappings = new ArrayList<DeferredEmbeddableOverrides>();
+ _deferredMappings.put(cls, defMappings);
+ }
+ defMappings.add(defMap);
+ }
+
+ /*
+ * Clean up any deferred mappings
+ */
+ @Override
+ protected void clearDeferredMetaData() {
+ super.clearDeferredMetaData();
+ _deferredMappings.clear();
+ }
+
+ /*
+ * Get embeddable overrides for the specified field mapping. If create
+ * is true, create a new override if one does not exist.
+ */
+ private DeferredEmbeddableOverrides
+ getDeferredFieldMappingInfo(Class<?> cls, FieldMapping fm,
+ String attrName, boolean create) {
+
+ ArrayList<DeferredEmbeddableOverrides> defMappings =
+ _deferredMappings.get(cls);
+
+ if (defMappings == null && create) {
+ defMappings = new ArrayList<DeferredEmbeddableOverrides>();
+ _deferredMappings.put(cls, defMappings);
+ }
+ DeferredEmbeddableOverrides dfm =
+ findDeferredMapping(cls, fm, attrName);
+
+ if (dfm == null & create) {
+ dfm = new DeferredEmbeddableOverrides(fm, attrName);
+ deferEmbeddableOverrides(cls, dfm);
+ }
+ return dfm;
+ }
+
+ /*
+ * Find deferred mappings for the given class, fm, and attr name
+ */
+ private DeferredEmbeddableOverrides findDeferredMapping(Class<?> cls,
+ FieldMapping fm, String attrName) {
+ ArrayList<DeferredEmbeddableOverrides> defMappings =
+ _deferredMappings.get(cls);
+ if (defMappings == null)
+ return null;
+
+ for (DeferredEmbeddableOverrides dfm : defMappings) {
+ if (dfm != null && dfm._fm == fm &&
+ attrName.equals(dfm._attrName))
+ return dfm;
+ }
+ return null;
+ }
+
+ // Inner class for storing override information
+ class DeferredEmbeddableOverrides {
+ DeferredEmbeddableOverrides(FieldMapping fm, String attrName) {
+ _fm = fm;
+ _attrName = attrName;
+ }
+ private FieldMapping _fm;
+ private List<Column> _defCols;
+ private List<Column> _defElemJoinCols;
+ private List<Column> _defJoinCols;
+ private String _defTable;
+ private String _attrName;
+ private EnumSet<UniqueFlag> _unique;
+ }
}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java?rev=783966&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java Fri Jun 12 02:40:14 2009
@@ -0,0 +1,39 @@
+/*
+ * 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.persistence.embed.attrOverrides;
+
+public class BasicEmbedXML {
+
+ private Integer intValue;
+
+ public BasicEmbedXML() {
+ }
+
+ public BasicEmbedXML(int integerValue) {
+ this.intValue = new Integer(integerValue);
+ }
+
+ public Integer getIntegerValue() {
+ return this.intValue;
+ }
+
+ public void setNotIntegerValue(Integer intValue) {
+ this.intValue = intValue;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEmbedXML.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java?rev=783966&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java Fri Jun 12 02:40:14 2009
@@ -0,0 +1,45 @@
+/*
+ * 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.persistence.embed.attrOverrides;
+
+import java.util.List;
+
+public class BasicEntityXML {
+
+ private int id;
+
+ private List<BasicEmbedXML> listIntAttrOverEmbed;
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setListIntAttrOverEmbed(
+ List<BasicEmbedXML> listIntAttrOverEmbed) {
+ this.listIntAttrOverEmbed = listIntAttrOverEmbed;
+ }
+
+ public List<BasicEmbedXML> getListIntAttrOverEmbed() {
+ return listIntAttrOverEmbed;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/BasicEntityXML.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/TestAttrOverridesXml.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/TestAttrOverridesXml.java?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/TestAttrOverridesXml.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/attrOverrides/TestAttrOverridesXml.java Fri Jun 12 02:40:14 2009
@@ -18,8 +18,11 @@
*/
package org.apache.openjpa.persistence.embed.attrOverrides;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
@@ -27,15 +30,14 @@
import junit.framework.Assert;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.test.AllowFailure;
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
-@AllowFailure(message=
- "Multi-level embedding" +
- "JPA 2.0 Access Style " +
- "XML Metadata " +
- "Attribute Override " +
- " is not yet supported")
public class TestAttrOverridesXml extends SQLListenerTestCase {
public int numPersons = 4;
@@ -51,6 +53,12 @@
return "embed-pu";
}
+ @AllowFailure(message=
+ "Multi-level embedding" +
+ "JPA 2.0 Access Style " +
+ "XML Metadata " +
+ "Attribute Override " +
+ " is not yet supported")
public void testAttrOverride1() {
sql.clear();
createObj1();
@@ -59,6 +67,31 @@
assertAttrOverrides("CustomerXml1");
}
+ /**
+ * This test verifies that an embeddable column attribute override defined
+ * in XML overrides the base column definition.
+ */
+ public void testBasicEmbedAttrOverride() {
+ OpenJPAEntityManagerSPI em = emf.createEntityManager();
+
+ BasicEntityXML be = new BasicEntityXML();
+ be.setId(new Random().nextInt());
+
+ BasicEmbedXML bem = new BasicEmbedXML();
+ bem.setNotIntegerValue(new Random().nextInt());
+ ArrayList<BasicEmbedXML> al = new ArrayList<BasicEmbedXML>();
+ al.add(bem);
+ be.setListIntAttrOverEmbed(al);
+
+ em.getTransaction().begin();
+ em.persist(be);
+ em.getTransaction().commit();
+
+ assertTrue(verifyColumnOverride(em, "listIntAttrOverEmbedColTable",
+ "intValueAttributeOverride"));
+ em.close();
+ }
+
public void createObj1() {
EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction();
@@ -120,4 +153,33 @@
if (!found)
fail();
}
+
+ private boolean verifyColumnOverride(
+ OpenJPAEntityManagerSPI em, String tableName,
+ String columnName) {
+
+ JDBCConfiguration conf = (JDBCConfiguration)
+ em.getEntityManagerFactory().getConfiguration();
+ DBDictionary dict = conf.getDBDictionaryInstance();
+
+ Connection conn = (Connection)em.getConnection();
+ try {
+ DatabaseMetaData dbmd = conn.getMetaData();
+ // (meta, catalog, schemaName, tableName, conn)
+ Column[] cols = dict.getColumns(dbmd, null, null,
+ tableName, columnName, conn);
+ if (cols != null && cols.length == 1) {
+ Column col = cols[0];
+ String colName = col.getName();
+ if (col.getTableName().equalsIgnoreCase(tableName) &&
+ colName.equalsIgnoreCase(columnName))
+ return true;
+ }
+ } catch (Throwable e) {
+ fail("Unable to get column information.");
+ }
+ return false;
+ }
+
+
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml Fri Jun 12 02:40:14 2009
@@ -184,6 +184,22 @@
</attributes>
</entity>
+ <entity name="BasicEntityXML"
+ class="org.apache.openjpa.persistence.embed.attrOverrides.BasicEntityXML">
+ <attributes>
+ <id name="id" />
+ <element-collection name="listIntAttrOverEmbed" fetch="EAGER">
+ <order-column name="valueOrderColumn" />
+ <attribute-override name="intValue">
+ <column name="intValueAttributeOverride" />
+ </attribute-override>
+ <collection-table name="listIntAttrOverEmbedColTable">
+ <join-column name="parent_id" />
+ </collection-table>
+ </element-collection>
+ </attributes>
+ </entity>
+
<embeddable
class="org.apache.openjpa.persistence.embed.attrOverrides.AddressXml"
access="FIELD">
@@ -235,4 +251,11 @@
</attributes>
</embeddable>
-</entity-mappings>
+ <embeddable class="org.apache.openjpa.persistence.embed.attrOverrides.BasicEmbedXML">
+ <attributes>
+ <basic name="intValue">
+ <column name="shouldNotExist" />
+ </basic>
+ </attributes>
+ </embeddable>
+</entity-mappings>
\ No newline at end of file
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=783966&r1=783965&r2=783966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Fri Jun 12 02:40:14 2009
@@ -1553,7 +1553,9 @@
FieldMetaData fmd = (FieldMetaData) currentElement();
String dec = currentText();
if (fmd.isElementCollection() &&
- fmd.getElement().getEmbeddedMetaData() != null) {
+ fmd.getElement().getEmbeddedMetaData() != null ||
+ isDeferredEmbeddable(fmd.getElement().getDeclaredType(),
+ fmd.getElement())) {
if (dec.length() == 0 || dec.equals("ASC") ||
dec.equals("DESC"))
throw new MetaDataException(_loc.get(
@@ -1895,34 +1897,58 @@
}
/**
- * Process all deferred embeddables for a given class. This should only
- * happen after the access type of the embeddable is known.
+ * Process all deferred embeddables and embeddable mapping overrides
+ * for a given class. This should only happen after the access type
+ * of the embeddable is known.
*
- * @param embedType embeddable class
+ * @param embedType embeddable class
* @param access class level access for embeddable
+ * @throws SAXException
*/
protected void addDeferredEmbeddableMetaData(Class<?> embedType,
- int access) {
+ int access) throws SAXException {
ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
if (fmds != null && fmds.size() > 0) {
- for (int i = fmds.size() -1 ; i >= 0; i--) {
- MetaDataContext md = fmds.get(i);
+ for (MetaDataContext md : fmds) {
if (md instanceof FieldMetaData) {
- ((FieldMetaData)md).addEmbeddedMetaData(access);
+ FieldMetaData fmd = (FieldMetaData)md;
+ fmd.addEmbeddedMetaData(access);
}
else if (md instanceof ValueMetaData) {
- ((ValueMetaData)md).addEmbeddedMetaData(access);
+ ValueMetaData vmd = (ValueMetaData)md;
+ vmd.addEmbeddedMetaData(access);
}
- fmds.remove(i);
- }
- // If all mds in the list were processed, remove the item
- // from the map.
- if (fmds.size() == 0) {
- _embeddables.remove(embedType);
}
+ applyDeferredEmbeddableOverrides(embedType);
+ // Clean up deferrals after they have been processed
+ fmds.clear();
+ _embeddables.remove(embedType);
+ }
+ }
+
+ /*
+ * Clear any deferred metadata
+ */
+ @Override
+ protected void clearDeferredMetaData() {
+ _embeddables.clear();
+ }
+
+ /*
+ * Determines whether the embeddable type is deferred.
+ */
+ protected boolean isDeferredEmbeddable(Class<?> embedType,
+ MetaDataContext fmd) {
+ ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
+ if (fmds != null) {
+ return fmds.contains(fmd);
}
+ return false;
}
+ /*
+ * Add the fmd to the defer list for for the given embeddable type
+ */
protected void deferEmbeddable(Class<?> embedType, MetaDataContext fmd) {
ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
if (fmds == null) {
@@ -1931,4 +1957,11 @@
}
fmds.add(fmd);
}
+
+ /*
+ * Apply any deferred overrides.
+ */
+ protected void applyDeferredEmbeddableOverrides(Class<?> cls)
+ throws SAXException {
+ }
}