You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/12/17 00:31:45 UTC
svn commit: r891476 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/
Author: fancy
Date: Wed Dec 16 23:31:44 2009
New Revision: 891476
URL: http://svn.apache.org/viewvc?rev=891476&view=rev
Log:
OPENJPA-1401 Inheritance using Join Strategy may fail in cross join JPQL
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Contractor.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Department.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Employee.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Person.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=891476&r1=891475&r2=891476&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java Wed Dec 16 23:31:44 2009
@@ -73,6 +73,7 @@
private static final int UNBOUND_VAR = 2;
private static final int UNACCESSED_VAR = 3;
private static final int XPATH = 4;
+ private static final int OBJECT_PATH = 5;
private static final Localizer _loc = Localizer.forPackage(PCPath.class);
@@ -412,6 +413,22 @@
_type = PATH;
}
+ private void checkObjectPathInheritanceTypeJoined(PathExpState pstate) {
+ // if this mapping is in InheritanceType.JOINED,
+ // then add joins
+ ClassMapping base = _class;
+ while (base.getJoinablePCSuperclassMapping() != null)
+ base = base.getJoinablePCSuperclassMapping();
+ if (base != _class) {
+ ClassMapping from = _class;
+ ClassMapping to = base;
+ _type = OBJECT_PATH;
+ for (; from != null && from != to; from = from.getJoinablePCSuperclassMapping()) {
+ pstate.joins = from.joinSuperclass(pstate.joins, false);
+ }
+ }
+ }
+
public FieldMetaData last() {
Action act = lastFieldAction();
return (act == null) ? null : isXPath() ?
@@ -445,7 +462,7 @@
Action act = lastFieldAction();
if (act != null && act.op == Action.GET_XPATH)
return ((XMLMetaData) act.data).getType();
-
+
FieldMetaData fld = (act == null) ? null : (FieldMetaData) act.data;
boolean key = act != null && act.op == Action.GET_KEY;
if (fld != null) {
@@ -529,6 +546,9 @@
pstate.joins = pstate.joins.crossJoin(_candidate.getTable(),
rel.getTable());
+ if (!itr.hasNext() && isVariable()) {
+ checkObjectPathInheritanceTypeJoined(pstate);
+ }
} else {
// move past the previous field, if any
field = (FieldMapping) ((action.op == Action.GET_XPATH) ?
@@ -626,6 +646,7 @@
String subqAlias = findSubqAlias(sel);
pstate.joins = pstate.joins.setSubselect(subqAlias);
pstate.joins.setCorrelatedVariable(_schemaAlias);
+ checkObjectPathInheritanceTypeJoined(pstate);
}
return pstate;
@@ -652,7 +673,7 @@
if (sel.getParent() == null)
return false;
Iterator itr = (_actions == null) ? null : _actions.iterator();
- boolean navigateFromRoot = false;
+
boolean hasVar = false;
boolean startsWithSubquery = false;
while (itr != null && itr.hasNext()) {
@@ -830,8 +851,8 @@
sel.setSchemaAlias(_schemaAlias);
ClassMapping mapping = getClassMapping(state);
PathExpState pstate = (PathExpState) state;
- if (mapping == null || !pstate.joinedRel ||
- pstate.isEmbedElementColl)
+ if (_type != OBJECT_PATH && (mapping == null || !pstate.joinedRel ||
+ pstate.isEmbedElementColl))
sel.select(getColumns(state), pstate.joins);
else if (_key && pstate.field.getKey().isEmbedded())
selectEmbeddedMapKey(sel, ctx, state);
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Contractor.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Contractor.java?rev=891476&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Contractor.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Contractor.java Wed Dec 16 23:31:44 2009
@@ -0,0 +1,81 @@
+/*
+ * 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.jointable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import org.apache.openjpa.persistence.jdbc.Index;
+
+@Inheritance(strategy=InheritanceType.JOINED)
+@Entity
+@Table(name="WContractor")
+public class Contractor extends Employee {
+ @Column(name="ContractorProp1",length=10)
+ @Basic
+ private String ctrProp1;
+
+
+ @ManyToOne(optional=true,cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
+ @JoinColumn(name="Dept_No",referencedColumnName="OID")
+ @Index
+ private Department dept;
+
+ public Contractor() {
+ }
+
+ public Contractor(String desc) {
+ setDescription(desc);
+ }
+
+ public String getCtrProp1() {
+ return ctrProp1;
+ }
+
+ public void setCtrProp1(String ctrProp1) {
+ this.ctrProp1 = ctrProp1;
+ }
+
+ public Department getDept() {
+ return dept;
+ }
+
+ public void setDept(Department dept) {
+ this.dept = dept;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof Contractor) {
+ Contractor c = (Contractor) other;
+ if (c.getOID() == this.getOID() &&
+ c.getDept() == this.getDept())
+ return true;
+ }
+ return false;
+ }
+}
+
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Department.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Department.java?rev=891476&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Department.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Department.java Wed Dec 16 23:31:44 2009
@@ -0,0 +1,92 @@
+/*
+ * 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.jointable;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Inheritance(strategy=InheritanceType.JOINED)
+@Entity
+@Table(name="WDept")
+public class Department {
+ @Id
+ @GeneratedValue(strategy=GenerationType.TABLE, generator="JWTGen")
+ private long OID;
+
+ @Basic
+ private String description;
+
+ @Column(name="DeptProp1",length=10)
+ @Basic
+ private String deptProp1;
+
+ @OneToMany(mappedBy="dept",cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
+ private java.util.Collection<Contractor> ctrs;
+
+ public Department() {
+ }
+
+ public Department(String desc) {
+ setDescription(desc);
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public long getOID() {
+ return OID;
+ }
+
+ public void setOID(long oid) {
+ this.OID = oid;
+ }
+
+
+ public String getDeptProp1() {
+ return deptProp1;
+ }
+
+ public void setDeptProp1(String deptProp1) {
+ this.deptProp1 = deptProp1;
+ }
+
+ public java.util.Collection<Contractor> getCtrs() {
+ return ctrs;
+ }
+
+ public void setCtrs(java.util.Collection<Contractor> ctrs) {
+ this.ctrs = ctrs;
+ }
+}
+
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Employee.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Employee.java?rev=891476&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Employee.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Employee.java Wed Dec 16 23:31:44 2009
@@ -0,0 +1,47 @@
+/*
+ * 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.jointable;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="WEmployee")
+@Inheritance(strategy=InheritanceType.JOINED)
+public abstract class Employee extends Person {
+
+ @Basic
+ private String description;
+
+ public Employee() {
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ super.setName("Name "+description);
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
+
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Person.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Person.java?rev=891476&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Person.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/Person.java Wed Dec 16 23:31:44 2009
@@ -0,0 +1,64 @@
+/*
+ * 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.jointable;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+@Entity
+@Table(name="WPerson")
+@Inheritance(strategy=InheritanceType.JOINED)
+@TableGenerator(name="JWTGen", table="JWT_GEN", pkColumnName="PK",
+ valueColumnName="ID")
+
+public abstract class Person {
+ @Id
+ @GeneratedValue(strategy=GenerationType.TABLE, generator="JWTGen")
+ private long OID;
+
+ @Basic
+ private String name;
+
+ public Person() {
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getOID() {
+ return OID;
+ }
+
+ public void setOID(long oid) {
+ this.OID = oid;
+ }
+}
+
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java?rev=891476&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java Wed Dec 16 23:31:44 2009
@@ -0,0 +1,159 @@
+/*
+ * 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.jointable;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+
+public class TestInheritanceTypeJoinedQuery extends SQLListenerTestCase {
+
+ public void setUp() {
+ setUp(Contractor.class, Employee.class, Department.class, Person.class,
+ CLEAR_TABLES);
+ populate();
+ }
+
+ public void populate() {
+ EntityManager em = emf.createEntityManager();
+
+ Department d = new Department("IT");
+ for (int i = 0; i < 3; i++) {
+ Contractor c = new Contractor("ctr" + i);
+ c.setDept(d);
+ em.persist(c);
+ }
+ em.persist(d);
+
+ em.getTransaction().begin();
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public void testInheritanceTypeJoinedQuery() {
+ EntityManager em = emf.createEntityManager();
+ Query q = null;
+ String qS = null;
+ Department dept = null;
+
+ qS = "SELECT c.OID, c.dept FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ List<Object[]> lResult = q.getResultList();
+ for (Object[] resultElement : lResult) {
+ Long oid = (Long)resultElement[0];
+ dept = (Department)resultElement[1];
+ }
+
+ qS = "SELECT c.OID FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ for (Object resultElement : q.getResultList()) {
+ Long oid = (Long)resultElement;
+ }
+
+ qS = "SELECT d FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ for (Department aResult: (List <Department>) q.getResultList()) {
+ assertEquals(dept.getOID(), aResult.getOID());
+ }
+
+ qS = "SELECT c FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ for (Contractor aResult: (List <Contractor>) q.getResultList()) {
+ //System.out.println(aResult.getDescription() + ", " + aResult.getOID());
+ assertEquals(dept.getOID(), aResult.getDept().getOID());
+ }
+ qS = "SELECT c FROM Contractor c, Department d where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ for (Contractor aResult: (List <Contractor>) q.getResultList()) {
+ assertEquals(dept.getOID(), aResult.getDept().getOID());
+ }
+
+ qS = "SELECT c, c.OID FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ List<Object[]> cResult = q.getResultList();
+ Contractor contractor = null;
+ for (Object[] resultElement : cResult) {
+ contractor = (Contractor)resultElement[0];
+ Long oid = (Long)resultElement[1];
+ assertTrue(contractor.getOID() == oid);
+ assertEquals(dept.getOID(), contractor.getDept().getOID());
+ }
+
+ qS = "SELECT c.OID, c FROM Contractor c, Department d where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ List<Object[]> dResult = q.getResultList();
+ for (Object[] resultElement : dResult) {
+ Long oid = (Long)resultElement[0];
+ contractor = (Contractor)resultElement[1];
+ assertTrue(contractor.getOID() == oid);
+ assertEquals(dept.getOID(), contractor.getDept().getOID());
+ }
+
+ qS = "SELECT c, c.OID FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ List<Object[]> eResult = q.getResultList();
+ for (Object[] resultElement : eResult) {
+ Long oid = (Long)resultElement[1];
+ contractor = (Contractor)resultElement[0];
+ assertTrue(contractor.getOID() == oid);
+ assertEquals(dept.getOID(), contractor.getDept().getOID());
+ }
+
+ qS = "SELECT c.OID, c FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT'";
+ q = em.createQuery(qS);
+ List<Object[]> fResult = q.getResultList();
+ for (Object[] resultElement : fResult) {
+ Long oid = (Long)resultElement[0];
+ Contractor c = (Contractor)resultElement[1];
+ assertTrue(oid.longValue() == c.getOID());
+ assertEquals(dept.getOID(), c.getDept().getOID());
+ }
+
+ qS = "SELECT d,c FROM Department d, Contractor c where d.OID = c.dept.OID and d.description = 'IT' " +
+ " and c = ?1";
+ q = em.createQuery(qS);
+ q.setParameter(1, contractor);
+ for (Object[] aResult: (List <Object[]>) q.getResultList()) {
+ System.out.println(((Department)aResult[0]).getOID() + ", " + ((Contractor)aResult[1]).getOID());
+ assertTrue(contractor.equals(aResult[1]));
+ }
+
+ qS = "SELECT c,d FROM Contractor c, Department d where d.OID = c.dept.OID and d.description = 'IT' " +
+ " and c = ?1";
+ q = em.createQuery(qS);
+ q.setParameter(1, contractor);
+ for (Object[] aResult: (List <Object[]>) q.getResultList()) {
+ System.out.println(((Contractor)aResult[0]).getOID() + ", " + ((Department)aResult[1]).getOID());
+ assertTrue(contractor.equals(aResult[0]));
+ }
+
+ qS = "SELECT p FROM Person p ";
+ q = em.createQuery(qS);
+ for (Object aResult: (List<Object>) q.getResultList()) {
+ assertTrue(aResult instanceof Contractor);
+ }
+
+ em.close();
+ }
+}
+