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:
Catalina Wei 2008-09-26 03:05:52 +00:00
parent 07c6b1e5dd
commit baa01d79dd
5 changed files with 314 additions and 5 deletions

View File

@ -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;

View File

@ -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 =

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}