mirror of https://github.com/apache/openjpa.git
OPENJPA-660: SQL Query Cache supports binding non-primary key parameters to cached SQL. Commit fix on behalf of Fay Wang. Original test case developed by Vikram Bhatia.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@678722 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4c0bf1be10
commit
b4c557d0c0
|
@ -38,6 +38,7 @@ import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.sql.Joins;
|
import org.apache.openjpa.jdbc.sql.Joins;
|
||||||
import org.apache.openjpa.jdbc.sql.LogicalUnion;
|
import org.apache.openjpa.jdbc.sql.LogicalUnion;
|
||||||
import org.apache.openjpa.jdbc.sql.Result;
|
import org.apache.openjpa.jdbc.sql.Result;
|
||||||
|
import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
||||||
import org.apache.openjpa.jdbc.sql.Select;
|
import org.apache.openjpa.jdbc.sql.Select;
|
||||||
import org.apache.openjpa.jdbc.sql.SelectExecutor;
|
import org.apache.openjpa.jdbc.sql.SelectExecutor;
|
||||||
import org.apache.openjpa.jdbc.sql.SelectImpl;
|
import org.apache.openjpa.jdbc.sql.SelectImpl;
|
||||||
|
@ -466,7 +467,7 @@ public abstract class StoreCollectionFieldStrategy
|
||||||
SelectImpl sel = null;
|
SelectImpl sel = null;
|
||||||
Map<JDBCStoreManager.SelectKey, Object[]> storeCollectionUnionCache = null;
|
Map<JDBCStoreManager.SelectKey, Object[]> storeCollectionUnionCache = null;
|
||||||
JDBCStoreManager.SelectKey selKey = null;
|
JDBCStoreManager.SelectKey selKey = null;
|
||||||
if (!((JDBCStoreManager)store).isQuerySQLCacheOn())
|
if (!((JDBCStoreManager)store).isQuerySQLCacheOn() || elems.length > 1)
|
||||||
union = newUnion(sm, store, fetch, elems, resJoins);
|
union = newUnion(sm, store, fetch, elems, resJoins);
|
||||||
else {
|
else {
|
||||||
parmList = new ArrayList();
|
parmList = new ArrayList();
|
||||||
|
@ -503,7 +504,7 @@ public abstract class StoreCollectionFieldStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
// only cache the union when elems length is 1 for now
|
// only cache the union when elems length is 1 for now
|
||||||
if (!found && elems.length == 1) {
|
if (!found) {
|
||||||
Object[] objs1 = new Object[2];
|
Object[] objs1 = new Object[2];
|
||||||
objs1[0] = union;
|
objs1[0] = union;
|
||||||
objs1[1] = resJoins[0];
|
objs1[1] = resJoins[0];
|
||||||
|
@ -531,6 +532,9 @@ public abstract class StoreCollectionFieldStrategy
|
||||||
|
|
||||||
sel.wherePrimaryKey(mapping, cols, cols, oid, store,
|
sel.wherePrimaryKey(mapping, cols, cols, oid, store,
|
||||||
null, null, parmList);
|
null, null, parmList);
|
||||||
|
List nonFKParams = sel.getSQL().getNonFKParameters();
|
||||||
|
if (nonFKParams != null && nonFKParams.size() > 0)
|
||||||
|
parmList.addAll(nonFKParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create proxy
|
// create proxy
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.commons.lang.ObjectUtils;
|
||||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||||
import org.apache.openjpa.jdbc.kernel.exps.Val;
|
import org.apache.openjpa.jdbc.kernel.exps.Val;
|
||||||
import org.apache.openjpa.jdbc.schema.Column;
|
import org.apache.openjpa.jdbc.schema.Column;
|
||||||
|
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Sequence;
|
import org.apache.openjpa.jdbc.schema.Sequence;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
import serp.util.Numbers;
|
import serp.util.Numbers;
|
||||||
|
@ -55,6 +56,7 @@ public final class SQLBuffer
|
||||||
private List _subsels = null;
|
private List _subsels = null;
|
||||||
private List _params = null;
|
private List _params = null;
|
||||||
private List _cols = null;
|
private List _cols = null;
|
||||||
|
private List _nonFKParams = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -145,6 +147,11 @@ public final class SQLBuffer
|
||||||
_cols.add(paramIndex, null);
|
_cols.add(paramIndex, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (buf._nonFKParams != null) {
|
||||||
|
if (_nonFKParams == null)
|
||||||
|
_nonFKParams = new ArrayList();
|
||||||
|
_nonFKParams.addAll(buf._nonFKParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLBuffer append(Table table) {
|
public SQLBuffer append(Table table) {
|
||||||
|
@ -249,6 +256,26 @@ public final class SQLBuffer
|
||||||
_params.add(o);
|
_params.add(o);
|
||||||
if (_cols != null)
|
if (_cols != null)
|
||||||
_cols.add(col);
|
_cols.add(col);
|
||||||
|
if (col == null)
|
||||||
|
return this;
|
||||||
|
boolean isFK = false;
|
||||||
|
ForeignKey[] fks = col.getTable().getForeignKeys();
|
||||||
|
for (int i = 0; i < fks.length; i++) {
|
||||||
|
Column[] cols = fks[i].getColumns();
|
||||||
|
for (int j = 0; j < cols.length; j++) {
|
||||||
|
if (cols[j] == col) {
|
||||||
|
isFK = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isFK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isFK) {
|
||||||
|
if (_nonFKParams == null)
|
||||||
|
_nonFKParams = new ArrayList();
|
||||||
|
_nonFKParams.add(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -372,6 +399,9 @@ public final class SQLBuffer
|
||||||
return (_params == null) ? Collections.EMPTY_LIST : _params;
|
return (_params == null) ? Collections.EMPTY_LIST : _params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List getNonFKParameters() {
|
||||||
|
return (_nonFKParams == null) ? Collections.EMPTY_LIST : _nonFKParams;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Return the SQL for this buffer.
|
* Return the SQL for this buffer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.jdbc.ElementClassCriteria;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent entity with collection whose element type belongs to inheritance
|
||||||
|
* hierarchy mapped to a SINGLE_TABLE. Hence relationship loading will require
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "DEPT")
|
||||||
|
@IdClass(DepartmentId.class)
|
||||||
|
public class Department {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
|
||||||
|
@ElementClassCriteria
|
||||||
|
private Collection<PartTimeEmployee> partTimeEmployees;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "dept", cascade = CascadeType.PERSIST)
|
||||||
|
@ElementClassCriteria
|
||||||
|
private Collection<FullTimeEmployee> fullTimeEmployees;
|
||||||
|
|
||||||
|
public Collection<FullTimeEmployee> getFullTimeEmployees() {
|
||||||
|
return fullTimeEmployees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEmployee(FullTimeEmployee e) {
|
||||||
|
if (fullTimeEmployees == null)
|
||||||
|
fullTimeEmployees = new ArrayList<FullTimeEmployee>();
|
||||||
|
this.fullTimeEmployees.add(e);
|
||||||
|
e.setDept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<PartTimeEmployee> getPartTimeEmployees() {
|
||||||
|
return partTimeEmployees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEmployee(PartTimeEmployee e) {
|
||||||
|
if (partTimeEmployees == null)
|
||||||
|
partTimeEmployees = new ArrayList<PartTimeEmployee>();
|
||||||
|
this.partTimeEmployees.add(e);
|
||||||
|
e.setDept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class DepartmentId implements Serializable {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public DepartmentId() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DepartmentId(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof DepartmentId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DepartmentId other = (DepartmentId) obj;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorColumn;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.Inheritance;
|
||||||
|
import javax.persistence.InheritanceType;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "EMP")
|
||||||
|
@IdClass(EmployeeId.class)
|
||||||
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||||
|
@DiscriminatorColumn(name = "TYPE")
|
||||||
|
public abstract class Employee {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String ssn;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Department dept;
|
||||||
|
|
||||||
|
public String getSsn() {
|
||||||
|
return ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSsn(String ssn) {
|
||||||
|
this.ssn = ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Department getDept() {
|
||||||
|
return dept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDept(Department dept) {
|
||||||
|
this.dept = dept;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class EmployeeId implements Serializable {
|
||||||
|
|
||||||
|
private String ssn;
|
||||||
|
|
||||||
|
public EmployeeId(){
|
||||||
|
}
|
||||||
|
public EmployeeId(String ssn){
|
||||||
|
this.ssn = ssn;
|
||||||
|
}
|
||||||
|
public boolean equals (Object other)
|
||||||
|
{
|
||||||
|
if (other == this)
|
||||||
|
return true;
|
||||||
|
if (!(other instanceof EmployeeId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EmployeeId obj = (EmployeeId) other;
|
||||||
|
if (ssn == null) {
|
||||||
|
if (obj.ssn != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!ssn.equals(obj.ssn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int hashCode ()
|
||||||
|
{
|
||||||
|
return (ssn.hashCode());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("F")
|
||||||
|
public class FullTimeEmployee extends Employee {
|
||||||
|
@Column(name = "salary")
|
||||||
|
private double salary;
|
||||||
|
|
||||||
|
public double getSalary() {
|
||||||
|
return salary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSalary(double salary) {
|
||||||
|
this.salary = salary;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("P")
|
||||||
|
public class PartTimeEmployee extends Employee {
|
||||||
|
@Column(name = "wage")
|
||||||
|
private double hourlyWage;
|
||||||
|
|
||||||
|
public double getHourlyWage() {
|
||||||
|
return hourlyWage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHourlyWage(double hourlyWage) {
|
||||||
|
this.hourlyWage = hourlyWage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.query.cache;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
|
||||||
|
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that find() queries that use non-primary keys can be cached.
|
||||||
|
*
|
||||||
|
* SQL Query Cache caches SQL queries generated to select single entity.
|
||||||
|
* However, single instance queries may also join to other relations. Hence,
|
||||||
|
* primary key and foreign keys are normally the parameters to these queries
|
||||||
|
* which cached query binds again when being reused.
|
||||||
|
*
|
||||||
|
* The test verifies the case where non-primary keys are used as query
|
||||||
|
* parameters. The test employs a inheritance hierarchy mapped to SINGLE_TABLE.
|
||||||
|
* When derived instances are used in relationship, the discriminator values
|
||||||
|
* must be used in to join to the target type.
|
||||||
|
*
|
||||||
|
* For further details, refer <A
|
||||||
|
* HREF="https://issues.apache.org/jira/browse/OPENJPA-660">OPENJPA-660</A>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Pinaki Poddar
|
||||||
|
* @author Vikram Bhatia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestNonPrimaryKeyQueryParameters extends SQLListenerTestCase {
|
||||||
|
private static final int FULLTIME_EMPLOYEE_COUNT = 3;
|
||||||
|
private static final int PARTTIME_EMPLOYEE_COUNT = 2;
|
||||||
|
private static final String DEPT_NAME = "ENGINEERING";
|
||||||
|
|
||||||
|
public void setUp() {
|
||||||
|
super.setUp(CLEAR_TABLES, Department.class, Employee.class,
|
||||||
|
FullTimeEmployee.class, PartTimeEmployee.class,
|
||||||
|
"openjpa.jdbc.QuerySQLCache", "true");
|
||||||
|
createDepartment(DEPT_NAME);
|
||||||
|
sql.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSelectQueryWithPrimaryKeyParameter() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
Query query = em
|
||||||
|
.createQuery("SELECT d from Department d where d.name=?1");
|
||||||
|
query.setParameter(1, DEPT_NAME);
|
||||||
|
Department dept = (Department) query.getSingleResult();
|
||||||
|
|
||||||
|
assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
|
||||||
|
.size());
|
||||||
|
assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
|
||||||
|
.size());
|
||||||
|
assertSQL(".* AND t0.TYPE = .*");
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSelectQueryWithNoParameter() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
Query query = em.createQuery("SELECT d from Department d");
|
||||||
|
query.setParameter(1, DEPT_NAME);
|
||||||
|
Department dept = (Department) query.getSingleResult();
|
||||||
|
|
||||||
|
assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
|
||||||
|
.size());
|
||||||
|
assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
|
||||||
|
.size());
|
||||||
|
|
||||||
|
assertSQL(".* AND t0.TYPE = .*");
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFind() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
Department dept = em.find(Department.class, DEPT_NAME);
|
||||||
|
|
||||||
|
assertEquals(FULLTIME_EMPLOYEE_COUNT, dept.getFullTimeEmployees()
|
||||||
|
.size());
|
||||||
|
assertEquals(PARTTIME_EMPLOYEE_COUNT, dept.getPartTimeEmployees()
|
||||||
|
.size());
|
||||||
|
|
||||||
|
assertSQL(".* AND t0.TYPE = .*");
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSelectSubClass() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
Query query = em.createQuery("SELECT e from FullTimeEmployee e");
|
||||||
|
assertEquals(FULLTIME_EMPLOYEE_COUNT, query.getResultList().size());
|
||||||
|
|
||||||
|
query = em.createQuery("SELECT e from PartTimeEmployee e");
|
||||||
|
assertEquals(PARTTIME_EMPLOYEE_COUNT, query.getResultList().size());
|
||||||
|
|
||||||
|
assertSQL(".* WHERE t0.TYPE = .*");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSelectBaseClass() {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
Query query = em.createQuery("SELECT e from Employee e");
|
||||||
|
assertEquals(FULLTIME_EMPLOYEE_COUNT + PARTTIME_EMPLOYEE_COUNT, query
|
||||||
|
.getResultList().size());
|
||||||
|
assertNotSQL(".* WHERE t0.TYPE = .*");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDepartment(String deptName) {
|
||||||
|
if (count(Department.class) > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Department dept = new Department();
|
||||||
|
dept.setName(deptName);
|
||||||
|
|
||||||
|
for (int i = 1; i <= FULLTIME_EMPLOYEE_COUNT; i++) {
|
||||||
|
FullTimeEmployee e = new FullTimeEmployee();
|
||||||
|
e.setSsn("888-PP-001" + i);
|
||||||
|
e.setSalary(100000);
|
||||||
|
dept.addEmployee(e);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= PARTTIME_EMPLOYEE_COUNT; i++) {
|
||||||
|
PartTimeEmployee e = new PartTimeEmployee();
|
||||||
|
e.setSsn("999-PP-001" + i);
|
||||||
|
e.setHourlyWage(20);
|
||||||
|
dept.addEmployee(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(dept);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue