mirror of
https://github.com/apache/openjpa.git
synced 2025-03-06 16:39:11 +00:00
OPENJPA-1989: Fix *ToOne xml fetch attribute to honor LAZY.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/2.1.x@1140188 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ade8ff1fb0
commit
4c3992fde3
@ -459,7 +459,7 @@ public class JDBCStoreManager
|
||||
}
|
||||
Object coll = owner.fetchObject(fms[i].getIndex());
|
||||
if (coll instanceof Map)
|
||||
coll = ((Map)coll).values();
|
||||
coll = ((Map<?,?>)coll).values();
|
||||
if (coll instanceof Collection<?> &&
|
||||
((Collection<?>) coll).size() > 0) {
|
||||
// Found eagerly loaded collection.
|
||||
@ -594,7 +594,7 @@ public class JDBCStoreManager
|
||||
|
||||
Union union = _sql.newUnion(mappings.length);
|
||||
union.setExpectedResultCount(1, false);
|
||||
if (fetch.getSubclassFetchMode(mapping) != fetch.EAGER_JOIN)
|
||||
if (fetch.getSubclassFetchMode(mapping) != EagerFetchModes.EAGER_JOIN)
|
||||
union.abortUnion();
|
||||
union.select(new Union.Selector() {
|
||||
public void select(Select sel, int i) {
|
||||
@ -823,7 +823,7 @@ public class JDBCStoreManager
|
||||
|
||||
ResultObjectProvider[] rops = null;
|
||||
final JDBCFetchConfiguration jfetch = (JDBCFetchConfiguration) fetch;
|
||||
if (jfetch.getSubclassFetchMode(mapping) != jfetch.EAGER_JOIN)
|
||||
if (jfetch.getSubclassFetchMode(mapping) != EagerFetchModes.EAGER_JOIN)
|
||||
rops = new ResultObjectProvider[mappings.length];
|
||||
|
||||
try {
|
||||
@ -1232,15 +1232,15 @@ public class JDBCStoreManager
|
||||
int mode;
|
||||
for (int i = 0; i < fms.length; i++) {
|
||||
mode = fms[i].getEagerFetchMode();
|
||||
if (mode == fetch.EAGER_NONE)
|
||||
if (mode == EagerFetchModes.EAGER_NONE)
|
||||
continue;
|
||||
if (!requiresSelect(fms[i], sm, fields, fetch))
|
||||
continue;
|
||||
|
||||
// try to select with join first
|
||||
jtype = (fms[i].getNullValue() == fms[i].NULL_EXCEPTION)
|
||||
? sel.EAGER_INNER : sel.EAGER_OUTER;
|
||||
if (mode != fetch.EAGER_PARALLEL && !fms[i].isEagerSelectToMany()
|
||||
jtype = (fms[i].getNullValue() == FieldMetaData.NULL_EXCEPTION)
|
||||
? Select.EAGER_INNER : Select.EAGER_OUTER;
|
||||
if (mode != EagerFetchModes.EAGER_PARALLEL && !fms[i].isEagerSelectToMany()
|
||||
&& fms[i].supportsSelect(sel, jtype, sm, this, fetch) > 0
|
||||
&& sel.eagerClone(fms[i], jtype, false, 1) != null)
|
||||
continue;
|
||||
@ -1252,8 +1252,8 @@ public class JDBCStoreManager
|
||||
// to use a to-many join also. currently we limit eager
|
||||
// outer joins to non-LRS, non-ranged selects that don't already
|
||||
// have an eager to-many join
|
||||
if ((hasJoin || mode == fetch.EAGER_JOIN
|
||||
|| (mode == fetch.DEFAULT && sm != null))
|
||||
if ((hasJoin || mode == EagerFetchModes.EAGER_JOIN
|
||||
|| (mode == FetchConfiguration.DEFAULT && sm != null))
|
||||
&& fms[i].isEagerSelectToMany()
|
||||
&& !inEagerJoin
|
||||
&& !sel.hasEagerJoin(true)
|
||||
@ -1268,8 +1268,8 @@ public class JDBCStoreManager
|
||||
}
|
||||
|
||||
// finally, try parallel
|
||||
if (eager == fetch.EAGER_PARALLEL
|
||||
&& (sels = fms[i].supportsSelect(sel, sel.EAGER_PARALLEL, sm,
|
||||
if (eager == EagerFetchModes.EAGER_PARALLEL
|
||||
&& (sels = fms[i].supportsSelect(sel, Select.EAGER_PARALLEL, sm,
|
||||
this, fetch)) != 0)
|
||||
sel.eagerClone(fms[i], Select.EAGER_PARALLEL,
|
||||
fms[i].isEagerSelectToMany(), sels);
|
||||
@ -1372,7 +1372,7 @@ public class JDBCStoreManager
|
||||
seld = Math.max(fseld, seld);
|
||||
} else if (optSelect(fms[i], sel, sm, fetch)) {
|
||||
fseld = fms[i].select(sel, sm, this,
|
||||
fetch.traverseJDBC(fms[i]), fetch.EAGER_NONE);
|
||||
fetch.traverseJDBC(fms[i]), EagerFetchModes.EAGER_NONE);
|
||||
|
||||
// don't upgrade seld to > 0 based on these fields, since
|
||||
// they're not in the calculated field set
|
||||
@ -1412,10 +1412,10 @@ public class JDBCStoreManager
|
||||
private boolean optSelect(FieldMapping fm, Select sel,
|
||||
OpenJPAStateManager sm, JDBCFetchConfiguration fetch) {
|
||||
return !fm.isInDefaultFetchGroup()
|
||||
&& !fm.isDefaultFetchGroupExplicit()
|
||||
&& !fm.isDefaultFetchGroupExplicit()
|
||||
&& (sm == null || sm.getPCState() == PCState.TRANSIENT
|
||||
|| !sm.getLoaded().get(fm.getIndex()))
|
||||
&& fm.supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) > 0;
|
||||
&& fm.supportsSelect(sel, Select.TYPE_TWO_PART, sm, this, fetch) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1458,7 +1458,7 @@ public class JDBCStoreManager
|
||||
if (fetch.requiresFetch(fms[j]) != FetchConfiguration.FETCH_LOAD
|
||||
&& ((!fms[j].isInDefaultFetchGroup()
|
||||
&& fms[j].isDefaultFetchGroupExplicit())
|
||||
|| fms[j].supportsSelect(sel, sel.TYPE_TWO_PART, sm, this,
|
||||
|| fms[j].supportsSelect(sel, Select.TYPE_TWO_PART, sm, this,
|
||||
fetch) <= 0))
|
||||
continue;
|
||||
|
||||
@ -1472,10 +1472,8 @@ public class JDBCStoreManager
|
||||
}
|
||||
|
||||
// if can select with tables already selected, do it
|
||||
if (fms[j].supportsSelect(sel, sel.TYPE_JOINLESS, sm, this,
|
||||
fetch) > 0)
|
||||
fms[j].select(sel, null, this, fetch.traverseJDBC(fms[j]),
|
||||
fetch.EAGER_NONE);
|
||||
if (fms[j].supportsSelect(sel, Select.TYPE_JOINLESS, sm, this, fetch) > 0)
|
||||
fms[j].select(sel, null, this, fetch.traverseJDBC(fms[j]), EagerFetchModes.EAGER_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.xml;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
||||
public class TestToOneLazyXmlOverride extends SQLListenerTestCase {
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp(CLEAR_TABLES, XmlOverrideToOneEntity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPersistenceUnitName() {
|
||||
return "to-one-xml-override";
|
||||
}
|
||||
|
||||
public void testToManyLazyOverride() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
try{
|
||||
em.getTransaction().begin();
|
||||
XmlOverrideToOneEntity x = new XmlOverrideToOneEntity();
|
||||
x.setOtherM2O(x);
|
||||
x.setOtherO2O(x);
|
||||
em.persist(x);
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.clear();
|
||||
resetSQL();
|
||||
|
||||
em.find(XmlOverrideToOneEntity.class, x.getId());
|
||||
|
||||
assertTrue(sql.size() == 1);
|
||||
String lastSql = sql.get(0);
|
||||
// Make sure we don't have any joins!
|
||||
assertFalse("Shouldn't have found any instances of join or JOIN in last sql, but did. Last SQL = "
|
||||
+ lastSql, lastSql.contains("join") || lastSql.contains("JOIN"));
|
||||
|
||||
// Make sure that we selected lazy join columns.
|
||||
assertTrue(lastSql.contains("o2o"));
|
||||
assertTrue(lastSql.contains("m2o"));
|
||||
|
||||
} finally {
|
||||
if (em.getTransaction().isActive()) {
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
|
||||
/*
|
||||
* 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.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@Entity
|
||||
public class XmlOverrideToOneEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
int id;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name="o2o")
|
||||
XmlOverrideToOneEntity otherO2O;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="m2o")
|
||||
XmlOverrideToOneEntity otherM2O;
|
||||
|
||||
@Version
|
||||
int version;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public XmlOverrideToOneEntity getOtherO2O() {
|
||||
return otherO2O;
|
||||
}
|
||||
|
||||
public void setOtherO2O(XmlOverrideToOneEntity otherO2O) {
|
||||
this.otherO2O = otherO2O;
|
||||
}
|
||||
|
||||
public XmlOverrideToOneEntity getOtherM2O() {
|
||||
return otherM2O;
|
||||
}
|
||||
|
||||
public void setOtherM2O(XmlOverrideToOneEntity otherM2O) {
|
||||
this.otherM2O = otherM2O;
|
||||
}
|
||||
|
||||
}
|
@ -385,4 +385,11 @@
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
<persistence-unit name="to-one-xml-override">
|
||||
<mapping-file>org/apache/openjpa/persistence/xml/toone-orm.xml
|
||||
</mapping-file>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?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_2_0.xsd"
|
||||
version="2.0">
|
||||
<package> org.apache.openjpa.persistence.xml </package>
|
||||
<entity name="XmlOverrideToOneEntity" class="XmlOverrideToOneEntity">
|
||||
<attributes>
|
||||
<many-to-one name="otherM2O" fetch="LAZY">
|
||||
<join-column name="m2o"/>
|
||||
</many-to-one>
|
||||
<one-to-one name="otherO2O" fetch="LAZY">
|
||||
<join-column name="o2o"/>
|
||||
</one-to-one>
|
||||
</attributes>
|
||||
</entity>
|
||||
</entity-mappings>
|
@ -1463,9 +1463,14 @@ public class XMLPersistenceMetaDataParser
|
||||
protected void parseOneToOne(FieldMetaData fmd, Attributes attrs)
|
||||
throws SAXException {
|
||||
String val = attrs.getValue("fetch");
|
||||
if (val == null || "EAGER".equals(val)) {
|
||||
fmd.setInDefaultFetchGroup(true);
|
||||
}
|
||||
boolean dfg = (val != null && val.equals("LAZY")) ? false : true;
|
||||
|
||||
// We need to toggle the DFG explicit flag here because this is used for an optimization when selecting an
|
||||
// Entity with lazy fields.
|
||||
fmd.setDefaultFetchGroupExplicit(true);
|
||||
fmd.setInDefaultFetchGroup(dfg);
|
||||
fmd.setDefaultFetchGroupExplicit(false);
|
||||
|
||||
val = attrs.getValue("target-entity");
|
||||
if (val != null)
|
||||
fmd.setTypeOverride(AnnotationPersistenceMetaDataParser.toOverrideType(classForName(val)));
|
||||
@ -1485,9 +1490,14 @@ public class XMLPersistenceMetaDataParser
|
||||
protected void parseManyToOne(FieldMetaData fmd, Attributes attrs)
|
||||
throws SAXException {
|
||||
String val = attrs.getValue("fetch");
|
||||
if (val == null || "EAGER".equals(val)) {
|
||||
fmd.setInDefaultFetchGroup(true);
|
||||
}
|
||||
boolean dfg = (val != null && val.equals("LAZY")) ? false : true;
|
||||
|
||||
// We need to toggle the DFG explicit flag here because this is used for an optimization when selecting an
|
||||
// Entity with lazy fields.
|
||||
fmd.setDefaultFetchGroupExplicit(true);
|
||||
fmd.setInDefaultFetchGroup(dfg);
|
||||
fmd.setDefaultFetchGroupExplicit(false);
|
||||
|
||||
val = attrs.getValue("target-entity");
|
||||
if (val != null)
|
||||
fmd.setTypeOverride(AnnotationPersistenceMetaDataParser.toOverrideType(classForName(val)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user