mirror of https://github.com/apache/openjpa.git
OPENJPA-1135 Correct access type related issues with attribute overrides and multi-level parsing.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@790150 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
80dbd79952
commit
0f45f13fc2
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 javax.persistence.Basic;
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class AnnoOverEmbed {
|
||||
|
||||
@Basic
|
||||
private int intEmbed;
|
||||
|
||||
@Basic
|
||||
private String strEmbed;
|
||||
|
||||
public void setIntEmbed(int intEmbed) {
|
||||
this.intEmbed = intEmbed;
|
||||
}
|
||||
|
||||
public int getIntEmbed() {
|
||||
return intEmbed;
|
||||
}
|
||||
|
||||
public void setStrEmbed(String strEmbed) {
|
||||
this.strEmbed = strEmbed;
|
||||
}
|
||||
|
||||
public String getStrEmbed() {
|
||||
return strEmbed;
|
||||
}
|
||||
}
|
|
@ -45,7 +45,9 @@ public class TestAttrOverridesXml extends SQLListenerTestCase {
|
|||
public int eId = 1;
|
||||
|
||||
public void setUp() {
|
||||
setUp(DROP_TABLES);
|
||||
setUp(
|
||||
org.apache.openjpa.persistence.embed.attrOverrides.AnnoOverEmbed.class,
|
||||
DROP_TABLES);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,6 +94,38 @@ public class TestAttrOverridesXml extends SQLListenerTestCase {
|
|||
em.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that an XML defined entity with an annotated
|
||||
* only embeddable has attribute overrides applied correctly.
|
||||
*/
|
||||
public void testXMLEntityWithAnnotatedOverrideEmbed() {
|
||||
OpenJPAEntityManagerSPI em = emf.createEntityManager();
|
||||
|
||||
XMLOverEntity xoe = new XMLOverEntity();
|
||||
xoe.setId(new Random().nextInt());
|
||||
|
||||
AnnoOverEmbed aoe = new AnnoOverEmbed();
|
||||
aoe.setIntEmbed(1);
|
||||
aoe.setStrEmbed("StrVal");
|
||||
xoe.setEmbed(aoe);
|
||||
|
||||
em.getTransaction().begin();
|
||||
em.persist(xoe);
|
||||
em.getTransaction().commit();
|
||||
|
||||
assertTrue(verifyColumnOverride(em, "XMLOverEntity",
|
||||
"intOverEmbed"));
|
||||
assertFalse(verifyColumnOverride(em, "XMLOverEntity",
|
||||
"intEmbed"));
|
||||
|
||||
assertTrue(verifyColumnOverride(em, "XMLOverEntity",
|
||||
"strOverEmbed"));
|
||||
assertFalse(verifyColumnOverride(em, "XMLOverEntity",
|
||||
"strEmbed"));
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void createObj1() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
EntityTransaction tran = em.getTransaction();
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 XMLOverEntity {
|
||||
|
||||
private int id;
|
||||
|
||||
private AnnoOverEmbed embed;
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setEmbed(AnnoOverEmbed embed) {
|
||||
this.embed = embed;
|
||||
}
|
||||
|
||||
public AnnoOverEmbed getEmbed() {
|
||||
return embed;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.inheritance;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.inheritance.entity.BaseCallback;
|
||||
import org.apache.openjpa.persistence.inheritance.entity.XMLCallback;
|
||||
import org.apache.openjpa.persistence.inheritance.entity.XMLSuperCallback;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
public class TestCallbackEntity
|
||||
extends SingleEMFTestCase {
|
||||
|
||||
@Override
|
||||
protected String getPersistenceUnitName() {
|
||||
return "AbstractCallbackPU";
|
||||
}
|
||||
|
||||
/*
|
||||
* This test verifies that the persistence metadata factory can create
|
||||
* and use separate copies of the XML metadata parser when a domain model
|
||||
* contains a base class with unknown access type and multi-level
|
||||
* inheritance of XML defined types. Per JPA spec, the superclass must
|
||||
* be queried to determine the access type.
|
||||
*/
|
||||
public void testCallbackEntity() {
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
BaseCallback bc = new BaseCallback();
|
||||
bc.setId(new Random().nextInt());
|
||||
bc.setName("BaseCallback");
|
||||
|
||||
// Persist the entity
|
||||
em.getTransaction().begin();
|
||||
em.persist(bc);
|
||||
em.getTransaction().commit();
|
||||
|
||||
// Assert callbacks fire expected # of times
|
||||
assertEquals(1, BaseCallback.postPersistCount);
|
||||
assertEquals(1, XMLCallback.prePersistCount);
|
||||
assertEquals(1, XMLSuperCallback.postPersistCount);
|
||||
|
||||
// Remove the entity
|
||||
em.getTransaction().begin();
|
||||
em.remove(bc);
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.inheritance.entity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.PostPersist;
|
||||
|
||||
/*
|
||||
* Annotated entity class with no persistent attributes or access type
|
||||
* defined. This is necessary to force query of the superclass to determine
|
||||
* the default access type.
|
||||
*/
|
||||
@Entity
|
||||
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
|
||||
public class BaseCallback extends XMLCallback {
|
||||
|
||||
public transient static int postPersistCount = 0;
|
||||
|
||||
@PostPersist
|
||||
public void basePostPersist() {
|
||||
postPersistCount++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.inheritance.entity;
|
||||
|
||||
/*
|
||||
* XML defined class with no persistent attributes, only a callback.
|
||||
*/
|
||||
public class XMLCallback extends XMLSuperCallback {
|
||||
|
||||
public transient static int prePersistCount = 0;
|
||||
|
||||
public void prePersist() {
|
||||
prePersistCount++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.inheritance.entity;
|
||||
|
||||
/*
|
||||
* XML defined entity superclass with no persistent attributes.
|
||||
*/
|
||||
public class XMLSuperCallback {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
public transient static int postPersistCount = 0;
|
||||
|
||||
public void superPostPersist() {
|
||||
postPersistCount++;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,9 @@ public class TestSimpleXmlEntity
|
|||
extends SingleEMTestCase {
|
||||
|
||||
public void setUp() {
|
||||
setUp(CLEAR_TABLES);
|
||||
setUp(
|
||||
org.apache.openjpa.persistence.embed.attrOverrides.AnnoOverEmbed.class,
|
||||
CLEAR_TABLES);
|
||||
}
|
||||
|
||||
protected String getPersistenceUnitName() {
|
||||
|
|
|
@ -34,7 +34,9 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
|||
public class TestXmlOverrideEntity extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() throws ClassNotFoundException {
|
||||
setUp(CLEAR_TABLES);
|
||||
setUp(
|
||||
org.apache.openjpa.persistence.embed.attrOverrides.AnnoOverEmbed.class,
|
||||
CLEAR_TABLES);
|
||||
|
||||
// make sure that XmlOverrideEntity is registered for our metadata tests
|
||||
Class.forName(XmlOverrideEntity.class.getName(), true,
|
||||
|
|
|
@ -47,7 +47,8 @@
|
|||
<mapping-file>org/apache/openjpa/persistence/access/access-pudef-prop-orm.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/jdbc/order/order-orm.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/jdbc/order/order-orm-2.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/jdbc/order/order-orm-3.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/jdbc/order/order-orm-3.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/inheritance/orm.xml</mapping-file>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema(ForeignKeys=true)"/>
|
||||
|
@ -120,6 +121,8 @@
|
|||
<class>org.apache.openjpa.persistence.embed.OrderXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.attrOverrides.AddressXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.attrOverrides.ZipcodeXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.attrOverrides.XMLOverEntity</class>
|
||||
<class>org.apache.openjpa.persistence.embed.attrOverrides.AnnoOverEmbed</class>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema(ForeignKeys=true)"/>
|
||||
|
@ -170,4 +173,16 @@
|
|||
value="buildSchema"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
<persistence-unit name="AbstractCallbackPU" transaction-type="RESOURCE_LOCAL">
|
||||
<description>PU for testing with an entity with no persistent attributes</description>
|
||||
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
|
||||
<mapping-file>org/apache/openjpa/persistence/inheritance/orm.xml</mapping-file>
|
||||
<class>org.apache.openjpa.persistence.inheritance.entity.BaseCallback</class>
|
||||
<class>org.apache.openjpa.persistence.inheritance.entity.XMLCallback</class>
|
||||
<class>org.apache.openjpa.persistence.inheritance.entity.XMLSuperCallback</class>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
|
@ -199,6 +199,22 @@ version="2.0">
|
|||
</element-collection>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
<entity name="XMLOverEntity"
|
||||
class="org.apache.openjpa.persistence.embed.attrOverrides.XMLOverEntity"
|
||||
access="FIELD">
|
||||
<attributes>
|
||||
<id name="id"/>
|
||||
<embedded name="embed">
|
||||
<attribute-override name="intEmbed">
|
||||
<column name="intOverEmbed"/>
|
||||
</attribute-override>
|
||||
<attribute-override name="strEmbed">
|
||||
<column name="strOverEmbed"/>
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
<embeddable
|
||||
class="org.apache.openjpa.persistence.embed.attrOverrides.AddressXml"
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<entity class="org.apache.openjpa.persistence.inheritance.entity.XMLCallback">
|
||||
<pre-persist method-name="prePersist" />
|
||||
</entity>
|
||||
<entity class="org.apache.openjpa.persistence.inheritance.entity.XMLSuperCallback"
|
||||
access="FIELD">
|
||||
<post-persist method-name="superPostPersist" />
|
||||
<attributes>
|
||||
<id name="id"/>
|
||||
<basic name="name"/>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
</entity-mappings>
|
|
@ -279,7 +279,8 @@ public class PersistenceMetaDataDefaults
|
|||
return null;
|
||||
Class<?> cls = meta.getDescribedType();
|
||||
Class<?> sup = cls.getSuperclass();
|
||||
if (sup == null)
|
||||
if (sup == null || "java.lang.Object".equals(
|
||||
sup.getName()))
|
||||
return null;
|
||||
MetaDataRepository repos = meta.getRepository();
|
||||
ClassMetaData supMeta = repos.getCachedMetaData(sup);
|
||||
|
@ -309,8 +310,13 @@ public class PersistenceMetaDataDefaults
|
|||
return access;
|
||||
|
||||
ClassMetaData sup = getCachedSuperclassMetaData(meta);
|
||||
while (sup != null && sup.isExplicitAccess())
|
||||
sup = getCachedSuperclassMetaData(sup);
|
||||
ClassMetaData tmpSup = sup;
|
||||
while (tmpSup != null && tmpSup.isExplicitAccess()) {
|
||||
tmpSup = getCachedSuperclassMetaData(tmpSup);
|
||||
if (tmpSup != null) {
|
||||
sup = tmpSup;
|
||||
}
|
||||
}
|
||||
if (sup != null && !AccessCode.isUnknown(sup))
|
||||
return sup.getAccessType();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -29,6 +30,8 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
@ -84,6 +87,9 @@ public class PersistenceMetaDataFactory
|
|||
private Set<URL> _unparsed = null; // xml rsrc
|
||||
private boolean _fieldOverride = true;
|
||||
|
||||
protected Stack<XMLPersistenceMetaDataParser> _stack =
|
||||
new Stack<XMLPersistenceMetaDataParser>();
|
||||
|
||||
/**
|
||||
* Whether to use field-level override or class-level override.
|
||||
* Defaults to true.
|
||||
|
@ -141,11 +147,23 @@ public class PersistenceMetaDataFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* Return XML metadata parser, creating it if it does not already exist.
|
||||
* Return XML metadata parser, creating it if it does not already exist or
|
||||
* if the existing parser is parsing.
|
||||
*/
|
||||
public XMLPersistenceMetaDataParser getXMLParser() {
|
||||
if (_xmlParser == null) {
|
||||
if (_xmlParser == null || _xmlParser.isParsing()) {
|
||||
Class<?> parseCls = null;
|
||||
ArrayList<Class<?>> parseList = null;
|
||||
// If there is an existing parser and it is parsing, push it on
|
||||
// the stack and return a new one.
|
||||
if (_xmlParser != null) {
|
||||
_stack.push(_xmlParser);
|
||||
parseCls = _xmlParser.getParseClass();
|
||||
parseList = _xmlParser.getParseList();
|
||||
}
|
||||
_xmlParser = newXMLParser(true);
|
||||
_xmlParser.addToParseList(parseList);
|
||||
_xmlParser.addToParseList(parseCls);
|
||||
_xmlParser.setRepository(repos);
|
||||
if (_fieldOverride)
|
||||
_xmlParser.setAnnotationParser(getAnnotationParser());
|
||||
|
@ -153,6 +171,15 @@ public class PersistenceMetaDataFactory
|
|||
return _xmlParser;
|
||||
}
|
||||
|
||||
public void resetXMLParser() {
|
||||
// If a parser was pushed on the stack due to multi-level parsing,
|
||||
// clear the current parser and pop the inner parser off the stack.
|
||||
if (!_stack.isEmpty()) {
|
||||
_xmlParser.clear();
|
||||
_xmlParser = _stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the metadata parser.
|
||||
*/
|
||||
|
@ -196,10 +223,12 @@ public class PersistenceMetaDataFactory
|
|||
boolean parsedXML = false;
|
||||
if (_unparsed != null && !_unparsed.isEmpty()
|
||||
&& (mode & MODE_META) != 0) {
|
||||
for (URL url : _unparsed)
|
||||
Set<URL> unparsed = new HashSet<URL>(_unparsed);
|
||||
for (URL url : unparsed) {
|
||||
parseXML(url, cls, mode, envLoader);
|
||||
parsedXML = _unparsed.contains(xml);
|
||||
_unparsed.clear();
|
||||
}
|
||||
parsedXML = unparsed.contains(xml);
|
||||
_unparsed.clear();
|
||||
|
||||
// XML process check
|
||||
meta = repos.getCachedMetaData(cls);
|
||||
|
@ -265,6 +294,9 @@ public class PersistenceMetaDataFactory
|
|||
} catch (IOException ioe) {
|
||||
throw new GeneralException(ioe);
|
||||
}
|
||||
finally {
|
||||
resetXMLParser();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -184,6 +184,8 @@ public class XMLPersistenceMetaDataParser
|
|||
private final Stack<Object> _parents = new Stack<Object>();
|
||||
|
||||
private Class<?> _cls = null;
|
||||
// List of classes currently being parsed
|
||||
private ArrayList<Class<?>> _parseList = new ArrayList<Class<?>>();
|
||||
private int _fieldPos = 0;
|
||||
private int _clsPos = 0;
|
||||
private int _access = AccessCode.UNKNOWN;
|
||||
|
@ -490,10 +492,14 @@ public class XMLPersistenceMetaDataParser
|
|||
|
||||
@Override
|
||||
protected void reset() {
|
||||
// Add all remaining deferred embeddable metadata
|
||||
addDeferredEmbeddableMetaData();
|
||||
|
||||
super.reset();
|
||||
_elements.clear();
|
||||
_parents.clear();
|
||||
_cls = null;
|
||||
_parseList.clear();
|
||||
_fieldPos = 0;
|
||||
_clsPos = 0;
|
||||
|
||||
|
@ -823,6 +829,12 @@ public class XMLPersistenceMetaDataParser
|
|||
|
||||
// query mode only?
|
||||
_cls = classForName(currentClassName());
|
||||
|
||||
// Prevent a reentrant parse for the same class
|
||||
if (parseListContains(_cls)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mode == MODE_QUERY) {
|
||||
if (_parser != null)
|
||||
_parser.parse(_cls);
|
||||
|
@ -1806,6 +1818,13 @@ public class XMLPersistenceMetaDataParser
|
|||
return false;
|
||||
|
||||
boolean system = currentElement() == null;
|
||||
|
||||
// If in a multi-level parse, do not add system level listeners.
|
||||
// Otherwise, they will get added multiple times.
|
||||
if (system && _parseList != null && _parseList.size() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Class<?> type = currentElement() == null ? null :
|
||||
((ClassMetaData) currentElement()).getDescribedType();
|
||||
if (type == null)
|
||||
|
@ -1895,7 +1914,30 @@ public class XMLPersistenceMetaDataParser
|
|||
return PersistenceCapable.class;
|
||||
return super.classForName(name, isRuntime());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process all deferred embeddables using an unknown access type.
|
||||
*/
|
||||
protected void addDeferredEmbeddableMetaData() {
|
||||
if (_embeddables != null && _embeddables.size() > 0) {
|
||||
// Reverse iterate the array of remaining deferred embeddables
|
||||
// since elements will be removed as they are processed.
|
||||
Class<?>[] classes = _embeddables.keySet().toArray(
|
||||
new Class<?>[_embeddables.size()]);
|
||||
for (int i = classes.length - 1 ; i >= 0; i--) {
|
||||
try {
|
||||
addDeferredEmbeddableMetaData(classes[i],
|
||||
AccessCode.UNKNOWN);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MetaDataException(
|
||||
_loc.get("no-embeddable-metadata",
|
||||
classes[i].getName()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all deferred embeddables and embeddable mapping overrides
|
||||
* for a given class. This should only happen after the access type
|
||||
|
@ -1964,4 +2006,45 @@ public class XMLPersistenceMetaDataParser
|
|||
protected void applyDeferredEmbeddableOverrides(Class<?> cls)
|
||||
throws SAXException {
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the array of classes to the active parse list.
|
||||
*/
|
||||
public void addToParseList(ArrayList<Class<?>> parseList) {
|
||||
if (parseList == null)
|
||||
return;
|
||||
_parseList.addAll(parseList);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the class to the active parse list.
|
||||
*/
|
||||
public void addToParseList(Class<?> parentCls) {
|
||||
if (parentCls == null)
|
||||
return;
|
||||
_parseList.add(parentCls);
|
||||
}
|
||||
|
||||
/*
|
||||
* Whether the active parse list contains the specified class.
|
||||
*/
|
||||
public boolean parseListContains(Class<?> cls) {
|
||||
if (_parseList.size() == 0)
|
||||
return false;
|
||||
return _parseList.contains(cls);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the list of classes actively being parsed.
|
||||
*/
|
||||
public ArrayList<Class<?>> getParseList() {
|
||||
return _parseList;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns class currently being parsed.
|
||||
*/
|
||||
public Class<?> getParseClass() {
|
||||
return _cls;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,4 +197,5 @@ dynamic-agent: OpenJPA dynamically loaded the class enhancer. Any classes \
|
|||
that were not enhanced at build time will be enhanced when they are \
|
||||
loaded by the JVM.
|
||||
vlem-creation-info: OpenJPA dynamically loaded a validation provider.
|
||||
no-embeddable-metadata: Unable to load metadata for embeddable class "{0}".
|
||||
|
||||
|
|
Loading…
Reference in New Issue