mirror of https://github.com/apache/openjpa.git
OPENJPA-731 Bug on FetchType.EAGER when QuerySQLCache is turned on
Committing patch provided by Fay Wang git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@699156 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
07c6b1e5dd
commit
baa01d79dd
|
@ -391,7 +391,7 @@ public class SelectImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate,
|
return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate,
|
||||||
_sql.getSQL());
|
_sql.getSQL(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isForUpdate(JDBCStore store, int lockLevel) {
|
private boolean isForUpdate(JDBCStore store, int lockLevel) {
|
||||||
|
@ -409,7 +409,7 @@ public class SelectImpl
|
||||||
* to the given result.
|
* to the given result.
|
||||||
*/
|
*/
|
||||||
private static void addEagerResults(SelectResult res, SelectImpl sel,
|
private static void addEagerResults(SelectResult res, SelectImpl sel,
|
||||||
JDBCStore store, JDBCFetchConfiguration fetch)
|
JDBCStore store, JDBCFetchConfiguration fetch, List params)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
if (sel._eager == null)
|
if (sel._eager == null)
|
||||||
return;
|
return;
|
||||||
|
@ -428,7 +428,7 @@ public class SelectImpl
|
||||||
eres = res;
|
eres = res;
|
||||||
else
|
else
|
||||||
eres = ((SelectExecutor) entry.getValue()).execute(store,
|
eres = ((SelectExecutor) entry.getValue()).execute(store,
|
||||||
fetch);
|
fetch, params);
|
||||||
|
|
||||||
eager = res.getEagerMap(false);
|
eager = res.getEagerMap(false);
|
||||||
if (eager == null) {
|
if (eager == null) {
|
||||||
|
@ -511,14 +511,15 @@ public class SelectImpl
|
||||||
*/
|
*/
|
||||||
protected Result getEagerResult(Connection conn,
|
protected Result getEagerResult(Connection conn,
|
||||||
PreparedStatement stmnt, ResultSet rs, JDBCStore store,
|
PreparedStatement stmnt, ResultSet rs, JDBCStore store,
|
||||||
JDBCFetchConfiguration fetch, boolean forUpdate, String sqlStr)
|
JDBCFetchConfiguration fetch, boolean forUpdate, String sqlStr,
|
||||||
|
List params)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
|
SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
|
||||||
res.setSelect(this);
|
res.setSelect(this);
|
||||||
res.setStore(store);
|
res.setStore(store);
|
||||||
res.setLocking(forUpdate);
|
res.setLocking(forUpdate);
|
||||||
try {
|
try {
|
||||||
addEagerResults(res, this, store, fetch);
|
addEagerResults(res, this, store, fetch, params);
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
res.close();
|
res.close();
|
||||||
throw se;
|
throw se;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.kernel;
|
package org.apache.openjpa.kernel;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -34,6 +35,9 @@ import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
|
||||||
import org.apache.openjpa.persistence.EntityManagerImpl;
|
import org.apache.openjpa.persistence.EntityManagerImpl;
|
||||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||||
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
||||||
|
import org.apache.openjpa.persistence.relations.TblChild;
|
||||||
|
import org.apache.openjpa.persistence.relations.TblGrandChild;
|
||||||
|
import org.apache.openjpa.persistence.relations.TblParent;
|
||||||
import org.apache.openjpa.persistence.simple.Person;
|
import org.apache.openjpa.persistence.simple.Person;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -271,6 +275,72 @@ public class TestQuerySQLCache
|
||||||
runMultiEMCaching(props);
|
runMultiEMCaching(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify QuerySQLCacheValue setting "true" uses the expected cache
|
||||||
|
* implementation and is caching.
|
||||||
|
*/
|
||||||
|
public void testEagerFetch() {
|
||||||
|
Map props = new HashMap(System.getProperties());
|
||||||
|
props.put("openjpa.MetaDataFactory", "jpa(Types="
|
||||||
|
+ TblChild.class.getName() + ";"
|
||||||
|
+ TblGrandChild.class.getName() + ";"
|
||||||
|
+ TblParent.class.getName() + ")");
|
||||||
|
props.put("openjpa.jdbc.QuerySQLCache", "true");
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.cast(
|
||||||
|
Persistence.createEntityManagerFactory("test", props));
|
||||||
|
|
||||||
|
EntityManagerImpl em = (EntityManagerImpl)emf.createEntityManager();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
TblParent p = new TblParent();
|
||||||
|
p.setParentId(i);
|
||||||
|
TblChild c = new TblChild();
|
||||||
|
c.setChildId(i);
|
||||||
|
c.setTblParent(p);
|
||||||
|
p.addTblChild(c);
|
||||||
|
em.persist(p);
|
||||||
|
em.persist(c);
|
||||||
|
|
||||||
|
TblGrandChild gc = new TblGrandChild();
|
||||||
|
gc.setGrandChildId(i);
|
||||||
|
gc.setTblChild(c);
|
||||||
|
c.addTblGrandChild(gc);
|
||||||
|
|
||||||
|
em.persist(p);
|
||||||
|
em.persist(c);
|
||||||
|
em.persist(gc);
|
||||||
|
}
|
||||||
|
em.flush();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
TblParent p = em.find(TblParent.class, i);
|
||||||
|
int pid = p.getParentId();
|
||||||
|
assertEquals(pid, i);
|
||||||
|
Collection<TblChild> children = p.getTblChildren();
|
||||||
|
boolean hasChild = false;
|
||||||
|
for (TblChild c : children) {
|
||||||
|
hasChild = true;
|
||||||
|
Collection<TblGrandChild> gchildren = c.getTblGrandChildren();
|
||||||
|
int cid = c.getChildId();
|
||||||
|
assertEquals(cid, i);
|
||||||
|
boolean hasGrandChild = false;
|
||||||
|
for (TblGrandChild gc : gchildren) {
|
||||||
|
hasGrandChild = true;
|
||||||
|
int gcId = gc.getGrandChildId();
|
||||||
|
assertEquals(gcId, i);
|
||||||
|
}
|
||||||
|
assertTrue(hasGrandChild);
|
||||||
|
}
|
||||||
|
assertTrue(hasChild);
|
||||||
|
}
|
||||||
|
em.close();
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void runMultiEMCaching(Map props) {
|
private void runMultiEMCaching(Map props) {
|
||||||
|
|
||||||
EntityManagerFactory emfac =
|
EntityManagerFactory emfac =
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* 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.relations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinColumns;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Version;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class TblChild {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "CHILD_ID",nullable=false)
|
||||||
|
private Integer childId;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
@Column(name = "VRS_NBR")
|
||||||
|
private Integer vrsNbr;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy="tblChild",fetch = FetchType.EAGER,
|
||||||
|
cascade = {CascadeType.PERSIST,CascadeType.MERGE})
|
||||||
|
private Collection<TblGrandChild> tblGrandChildren =
|
||||||
|
new ArrayList<TblGrandChild>();
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY,
|
||||||
|
cascade = {CascadeType.PERSIST,CascadeType.MERGE })
|
||||||
|
@JoinColumns({@JoinColumn(name =
|
||||||
|
"PARENT_ID",referencedColumnName="PARENT_ID")})
|
||||||
|
@ForeignKey
|
||||||
|
private TblParent tblParent;
|
||||||
|
|
||||||
|
public Integer getChildId() {
|
||||||
|
return childId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildId(Integer childId) {
|
||||||
|
this.childId = childId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getVrsNbr() {
|
||||||
|
return vrsNbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVrsNbr(Integer vrsNbr) {
|
||||||
|
this.vrsNbr = vrsNbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<TblGrandChild> getTblGrandChildren() {
|
||||||
|
return tblGrandChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTblGrandChildren(Collection<TblGrandChild>
|
||||||
|
tblGrandChildren) {
|
||||||
|
this.tblGrandChildren = tblGrandChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTblGrandChild(TblGrandChild tblGrandChild) {
|
||||||
|
tblGrandChild.setTblChild(this);
|
||||||
|
tblGrandChildren.add(tblGrandChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTblGrandChild(TblGrandChild tblGrandChild) {
|
||||||
|
tblGrandChild.setTblChild(null);
|
||||||
|
tblGrandChildren.remove(tblGrandChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TblParent getTblParent() {
|
||||||
|
return tblParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTblParent(TblParent tblParent) {
|
||||||
|
this.tblParent = tblParent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.relations;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinColumns;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Version;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.jdbc.ForeignKey;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class TblGrandChild {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "GC_ID",nullable=false)
|
||||||
|
private Integer grandChildId;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
@Column(name = "VRS_NBR")
|
||||||
|
private Integer vrsNbr;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY,
|
||||||
|
cascade = {CascadeType.PERSIST,CascadeType.MERGE })
|
||||||
|
@JoinColumns({@JoinColumn(name =
|
||||||
|
"CHILD_ID",referencedColumnName="CHILD_ID")})
|
||||||
|
@ForeignKey
|
||||||
|
private TblChild tblChild;
|
||||||
|
|
||||||
|
public Integer getGrandChildId() {
|
||||||
|
return grandChildId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGrandChildId(Integer grandChildId) {
|
||||||
|
this.grandChildId = grandChildId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getVrsNbr() {
|
||||||
|
return vrsNbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVrsNbr(Integer vrsNbr) {
|
||||||
|
this.vrsNbr = vrsNbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TblChild getTblChild() {
|
||||||
|
return tblChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTblChild(TblChild tblChild) {
|
||||||
|
this.tblChild = tblChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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.relations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
@Entity
|
||||||
|
public class TblParent {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "PARENT_ID")
|
||||||
|
private Integer parentId;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy="tblParent",fetch = FetchType.LAZY,cascade = {
|
||||||
|
CascadeType.PERSIST,CascadeType.MERGE })
|
||||||
|
private Collection<TblChild> tblChildren = new ArrayList<TblChild>();
|
||||||
|
|
||||||
|
public Integer getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentId(Integer parentId) {
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<TblChild> getTblChildren() {
|
||||||
|
return tblChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTblChildren(Collection<TblChild> tblChildren) {
|
||||||
|
this.tblChildren = tblChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTblChild(TblChild tblChild) {
|
||||||
|
tblChildren.add(tblChild);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue