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 2010/07/23 22:15:07 UTC
svn commit: r967240 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-jdbc/src/main/java/org/...
Author: faywang
Date: Fri Jul 23 20:15:06 2010
New Revision: 967240
URL: http://svn.apache.org/viewvc?rev=967240&view=rev
Log:
OPENJPA-1740: fix Type expression when entities use Joined table strategy.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java (with props)
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualTypeExpression.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ExpContext.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NotEqualTypeExpression.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.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/JDBCStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java Fri Jul 23 20:15:06 2010
@@ -363,22 +363,59 @@ public class JDBCStoreQuery
sel.setExpectedResultCount(optHint.intValue(), true);
else if (this.ctx.isUnique())
sel.setExpectedResultCount(1, false);
- for (int j = 0; j < verts.length; j++) {
- selMappings.add(verts[j]);
- if (j == verts.length - 1) {
- nextBits.set(sels.size());
- sels.add(sel);
- } else
- sels.add(sel.fullClone(1));
+
+ List selectFrom = getJoinedTableMeta(sel);
+ int size = 0;
+ if (selectFrom != null) {
+ size = selectFrom.size();
+ for (int j = 0; j < size; j++) {
+ ClassMapping vert = (ClassMapping)selectFrom.get(j);
+ selMappings.add(vert);
+ if (j == size - 1) {
+ nextBits.set(sels.size());
+ sel.select(vert.getPrimaryKeyColumns(), null);
+ sels.add(sel);
+ } else {
+ SelectImpl selClone = (SelectImpl)sel.fullClone(1);
+ selClone.select(vert.getPrimaryKeyColumns(), null);
+ sels.add(selClone);
+ }
+ }
+ } else {
+ for (int j = 0; j < verts.length; j++) {
+ selMappings.add(verts[j]);
+ if (j == verts.length - 1) {
+ nextBits.set(sels.size());
+ sels.add(sel);
+ } else
+ sels.add(sel.fullClone(1));
+ }
}
-
+
// turn off unioning if a given independent mapping requires
// multiple selects, or if we're using FROM selects
- if (verts.length > 1 || sel.getFromSelect() != null)
+ if (verts.length > 1 || size > 1 || sel.getFromSelect() != null)
unionable = false;
}
return unionable;
}
+
+ private List getJoinedTableMeta(Select sel) {
+ List selectFrom = sel.getJoinedTableClassMeta();
+ List exSelectFrom = sel.getExcludedJoinedTableClassMeta();
+ if (exSelectFrom == null)
+ return selectFrom;
+ if (selectFrom == null)
+ return null;
+ int size = selectFrom.size();
+ List retList = new ArrayList(size);
+ for (int i = 0; i < size; i++) {
+ Object obj = selectFrom.get(i);
+ if (!exSelectFrom.contains(obj))
+ retList.add(obj);
+ }
+ return retList;
+ }
/**
* Return all the vertical mappings to select separately. Depends on
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualTypeExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualTypeExpression.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualTypeExpression.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualTypeExpression.java Fri Jul 23 20:15:06 2010
@@ -18,9 +18,14 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.meta.ClassMetaData;
/**
* Compares two entity types.
@@ -37,6 +42,30 @@ class EqualTypeExpression
super(val1, val2);
}
+ private ClassMapping getSubClassMapping(Val val1, Val val2, ExpContext ctx) {
+ ClassMapping sub = null;
+ Val val = val1 instanceof Type ? val2 : val1;
+ if (val instanceof TypeLit)
+ sub = (ClassMapping) val.getMetaData();
+ else if (val instanceof Param)
+ sub = ((Param) val).getValueMetaData(ctx);
+ if (sub != null)
+ ctx.isVerticalStrat = sub.isVerticalStrategy();
+ return sub;
+ }
+
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer buf) {
+ Val val1 = getValue1();
+ Val val2 = getValue2();
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ if (ctx.isVerticalStrat) {
+ appendTo(sel, ctx, (BinaryOpExpState)state, buf, false, false);
+ return;
+ }
+ super.appendTo(sel, ctx, state, buf);
+ }
+
public void appendTo(Select sel, ExpContext ctx, BinaryOpExpState bstate,
SQLBuffer buf, boolean val1Null, boolean val2Null) {
if (val1Null && val2Null)
@@ -59,17 +88,16 @@ class EqualTypeExpression
Val val2 = getValue2();
if (val1.length(sel, ctx, bstate.state1) == 1
&& val2.length(sel, ctx, bstate.state2) == 1) {
- String op = "=";
- if (sel.getTablePerClassMeta() != null) {
- if (val1 instanceof Type) {
- if ((ClassMapping) val2.getMetaData() != sel.getTablePerClassMeta())
- op = "<>";
- }
- else {
- if ((ClassMapping) val1.getMetaData() != sel.getTablePerClassMeta())
- op = "<>";
- }
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ if (ctx.isVerticalStrat) {
+ processVerticalTypeAppend(sel, val1, val2, ctx, buf);
+ return;
}
+
+ String op = "=";
+ if (sel.getTablePerClassMeta() != null && sub != sel.getTablePerClassMeta())
+ op = "<>";
+
ctx.store.getDBDictionary().comparison(buf, op,
new FilterValueImpl(sel, ctx, bstate.state1, val1),
new FilterValueImpl(sel, ctx, bstate.state2, val2));
@@ -87,4 +115,27 @@ class EqualTypeExpression
}
}
}
+
+ void processVerticalTypeAppend(Select sel, Val val1, Val val2, ExpContext ctx,
+ SQLBuffer buf) {
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ List selectFrom = sel.getJoinedTableClassMeta();
+ if (selectFrom == null) {
+ selectFrom = new ArrayList();
+ sel.setJoinedTableClassMeta(selectFrom);
+ }
+ ClassMapping cm1 = (ClassMapping)((val1 instanceof Type) ? val1.getMetaData() :
+ val1.getMetaData());
+ if (sub.isVerticalStrategy()) {
+ ClassMetaData[] subs = cm1.getPCSubclassMetaDatas();
+ for (int i = 0; i < subs.length; i++) {
+ if (!Modifier.isAbstract(subs[i].getDescribedType().getModifiers()) && subs[i] == sub
+ && !selectFrom.contains(subs[i]))
+ selectFrom.add(subs[i]);
+ }
+ buf.append("1=1");
+ return;
+ }
+ }
+
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ExpContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ExpContext.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ExpContext.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ExpContext.java Fri Jul 23 20:15:06 2010
@@ -46,6 +46,8 @@ public class ExpContext {
public JDBCFetchConfiguration fetch;
public ClassMapping tpcMeta = null;
+
+ public boolean isVerticalStrat = false;
public ExpContext() {
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java Fri Jul 23 20:15:06 2010
@@ -24,8 +24,8 @@ import java.util.Date;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
import org.apache.openjpa.jdbc.sql.DBDictionary;
-import org.apache.openjpa.jdbc.sql.PostgresDictionary;
import org.apache.openjpa.jdbc.sql.Raw;
import org.apache.openjpa.kernel.exps.AggregateListener;
import org.apache.openjpa.kernel.exps.Arguments;
@@ -574,4 +574,14 @@ public class JDBCExpressionFactory
public Value newFunction(String functionName, Class<?> resultType, Value... args) {
return new DatastoreFunction(functionName, resultType, newArgumentList(args));
}
+
+ public boolean isVerticalType(Value val) {
+ if (!(val instanceof Type))
+ return false;
+ ClassMapping cm = (ClassMapping)((Type)val).getMetaData();
+ String strat = cm.getMappingInfo().getHierarchyStrategy();
+ if (strat != null && strat.equals(VerticalClassStrategy.ALIAS))
+ return true;
+ return false;
+ }
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NotEqualTypeExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NotEqualTypeExpression.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NotEqualTypeExpression.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NotEqualTypeExpression.java Fri Jul 23 20:15:06 2010
@@ -18,9 +18,14 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.meta.ClassMetaData;
/**
* Compares two entity types.
@@ -37,6 +42,31 @@ class NotEqualTypeExpression
super(val1, val2);
}
+ private ClassMapping getSubClassMapping(Val val1, Val val2, ExpContext ctx) {
+ ClassMapping sub = null;
+ Val val = val1 instanceof Type ? val2 : val1;
+ if (val instanceof TypeLit)
+ sub = (ClassMapping) val.getMetaData();
+ else if (val instanceof Param)
+ sub = ((Param) val).getValueMetaData(ctx);
+ if (sub != null)
+ ctx.isVerticalStrat = sub.isVerticalStrategy();
+ return sub;
+ }
+
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer buf) {
+ Val val1 = getValue1();
+ Val val2 = getValue2();
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ if (ctx.isVerticalStrat) {
+ appendTo(sel, ctx, (BinaryOpExpState)state, buf, false, false);
+ return;
+ }
+
+ super.appendTo(sel, ctx, state, buf);
+ }
+
public void appendTo(Select sel, ExpContext ctx, BinaryOpExpState bstate,
SQLBuffer buf, boolean val1Null, boolean val2Null) {
if (val1Null && val2Null)
@@ -59,14 +89,19 @@ class NotEqualTypeExpression
Val val2 = getValue2();
if (val1.length(sel, ctx, bstate.state1) == 1
&& val2.length(sel, ctx, bstate.state2) == 1) {
- String op = "<>";
- if (val1 instanceof Type)
- if ((ClassMapping) val2.getMetaData() != sel.getTablePerClassMeta())
- op = "=";
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ if (ctx.isVerticalStrat) {
+ processVerticalTypeAppend(sel, val1, val2, ctx, buf);
+ return;
+ }
+
+ String op;
+ if (sub != sel.getTablePerClassMeta())
+ op = "=";
else
- if ((ClassMapping) val1.getMetaData() != sel.getTablePerClassMeta())
- op = "=";
- ctx.store.getDBDictionary().comparison(buf, op,
+ op = "<>";
+
+ ctx.store.getDBDictionary().comparison(buf, op,
new FilterValueImpl(sel, ctx, bstate.state1, val1),
new FilterValueImpl(sel, ctx, bstate.state2, val2));
} else {
@@ -84,4 +119,33 @@ class NotEqualTypeExpression
}
}
}
+
+ void processVerticalTypeAppend(Select sel, Val val1, Val val2, ExpContext ctx,
+ SQLBuffer buf) {
+ ClassMapping sub = getSubClassMapping(val1, val2, ctx);
+ ClassMapping cm1 = (ClassMapping)((val1 instanceof Type) ? val1.getMetaData() :
+ val1.getMetaData());
+ if (sub != null && sub.isVerticalStrategy()) {
+ ClassMetaData[] subs = cm1.getPCSubclassMetaDatas();
+ List exSelectFrom = sel.getExcludedJoinedTableClassMeta();
+ if (exSelectFrom == null) {
+ exSelectFrom = new ArrayList();
+ sel.setExcludedJoinedTableClassMeta(exSelectFrom);
+ }
+ List selectFrom = sel.getJoinedTableClassMeta();
+ exSelectFrom.add(sub);
+ if (selectFrom == null) {
+ selectFrom = new ArrayList();
+ sel.setJoinedTableClassMeta(selectFrom);
+ }
+
+ for (int i = 0; i < subs.length; i++) {
+ if (!Modifier.isAbstract(subs[i].getDescribedType().getModifiers()) &&
+ !selectFrom.contains(subs[i]))
+ selectFrom.add(subs[i]);
+ }
+ buf.append("1=1");
+ return;
+ }
+ }
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java Fri Jul 23 20:15:06 2010
@@ -75,6 +75,14 @@ public class Param
_idx = idx;
}
+ public ClassMapping getValueMetaData(ExpContext ctx) {
+ Object[] params = ctx.params;
+ if (params[_idx] != null && params[_idx] instanceof Class)
+ return (ClassMapping) ctx.store.getConfiguration().getMetaDataRepositoryInstance().
+ getMetaData((Class) params[_idx], getClass().getClassLoader(), true);
+ return null;
+ }
+
public Object getValue(Object[] params) {
return Filters.convert(params[_idx], getType());
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java Fri Jul 23 20:15:06 2010
@@ -34,6 +34,7 @@ import org.apache.openjpa.enhance.Reflec
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.strats.NoneClassStrategy;
+import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.jdbc.schema.ForeignKey;
@@ -1101,4 +1102,11 @@ public class ClassMapping
}
return result;
}
+
+ public boolean isVerticalStrategy() {
+ String strat = getMappingInfo().getHierarchyStrategy();
+ if (strat != null && strat.equals(VerticalClassStrategy.ALIAS))
+ return true;
+ return false;
+ }
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Fri Jul 23 20:15:06 2010
@@ -911,6 +911,22 @@ public class LogicalUnion
public ClassMapping getTablePerClassMeta() {
return sel.getTablePerClassMeta();
}
+
+ public void setJoinedTableClassMeta(List meta) {
+ sel.setJoinedTableClassMeta(meta);
+ }
+
+ public List getJoinedTableClassMeta() {
+ return sel.getJoinedTableClassMeta();
+ }
+
+ public void setExcludedJoinedTableClassMeta(List meta) {
+ sel.setExcludedJoinedTableClassMeta(meta);
+ }
+
+ public List getExcludedJoinedTableClassMeta() {
+ return sel.getExcludedJoinedTableClassMeta();
+ }
}
/**
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java Fri Jul 23 20:15:06 2010
@@ -747,4 +747,24 @@ public interface Select
* get table-per-class metadata for polymorphic queries
*/
public ClassMapping getTablePerClassMeta();
+
+ /**
+ * Set joined table metadatas for polymorphic queries
+ */
+ public void setJoinedTableClassMeta(List meta);
+
+ /**
+ * get joined table metadatas for polymorphic queries
+ */
+ public List getJoinedTableClassMeta();
+
+ /**
+ * Set joined table metadatas excluded for polymorphic queries
+ */
+ public void setExcludedJoinedTableClassMeta(List meta);
+
+ /**
+ * get joined table metadatas excluded for polymorphic queries
+ */
+ public List getExcludedJoinedTableClassMeta();
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Fri Jul 23 20:15:06 2010
@@ -170,12 +170,32 @@ public class SelectImpl
// A path navigation is begin with this schema alias
private String _schemaAlias = null;
private ClassMapping _tpcMeta = null;
+ private List _joinedTables = null;
+ private List _exJoinedTables = null;
+
public ClassMapping getTablePerClassMeta() {
return _tpcMeta;
}
public void setTablePerClassMeta(ClassMapping meta) {
_tpcMeta = meta;
}
+
+ public void setJoinedTableClassMeta(List meta) {
+ _joinedTables = meta;
+ }
+
+ public List getJoinedTableClassMeta() {
+ return _joinedTables;
+ }
+
+ public void setExcludedJoinedTableClassMeta(List meta) {
+ _exJoinedTables = meta;
+ }
+
+ public List getExcludedJoinedTableClassMeta() {
+ return _exJoinedTables;
+ }
+
/**
* Helper method to return the proper table alias for the given alias index.
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java Fri Jul 23 20:15:06 2010
@@ -496,4 +496,9 @@ public interface ExpressionFactory {
* Return a value representing the given datastore function with the given arguments.
*/
public Value newFunction(String functionName, Class<?> resultType, Value... args);
+
+ /**
+ * Return true if the Value is a Type expression and the Type uses joined table strategy.
+ */
+ public boolean isVerticalType(Value val);
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java Fri Jul 23 20:15:06 2010
@@ -796,4 +796,8 @@ public class InMemoryExpressionFactory
public Value newFunction(String functionName, Class<?> resultType, Value... args) {
throw new AbstractMethodError();
}
+
+ public boolean isVerticalType(Value val) {
+ return false;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java Fri Jul 23 20:15:06 2010
@@ -35,7 +35,6 @@ import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
-import org.apache.commons.collections.map.LinkedMap;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.kernel.BrokerFactory;
@@ -1137,23 +1136,33 @@ public class JPQLExpressionBuilder
// special case for <value> IN (<subquery>) or
// <value> IN (<single value>)
- if (!(val2 instanceof Literal) && node.getChildCount() == 2)
+ if (useContains(not, val1, val2, node))
return evalNot(not, factory.contains(val2, val1));
// this is currently a sequence of OR expressions, since we
// do not have support for IN expressions
setImplicitTypes(val1, val2, null);
- if (inExp == null)
- inExp = factory.equal(val1, val2);
- else
- inExp = factory.or(inExp, factory.equal(val1, val2));
+ if (isVerticalTypeInExpr(val1, node) && not) {
+ if (inExp == null)
+ inExp = factory.notEqual(val1, val2);
+ else
+ inExp = factory.and(inExp, factory.notEqual(val1, val2));
+ } else {
+ if (inExp == null)
+ inExp = factory.equal(val1, val2);
+ else
+ inExp = factory.or(inExp, factory.equal(val1, val2));
+ }
}
// we additionally need to add in a "NOT NULL" clause, since
// the IN behavior that is expected by the CTS also expects
// to filter our NULLs
- return and(evalNot(not, inExp),
- factory.notEqual(val1, factory.getNull()));
+ if (isVerticalTypeInExpr(val1, node))
+ return inExp;
+ else
+ return and(evalNot(not, inExp),
+ factory.notEqual(val1, factory.getNull()));
case JJTISNULL: // x.field IS [NOT] NULL
val1 = getValue(onlyChild(node));
@@ -1414,6 +1423,19 @@ public class JPQLExpressionBuilder
}
}
+ private boolean useContains(boolean not, Value val1, Value val2, JPQLNode node) {
+ if (isVerticalTypeInExpr(val1, node) && not)
+ return false;
+ else
+ return (!(val2 instanceof Literal) && node.getChildCount() == 2);
+ }
+
+ private boolean isVerticalTypeInExpr(Value val, JPQLNode node) {
+ if (node.id != JJTIN)
+ return false;
+ return factory.isVerticalType(val);
+ }
+
private Value getIntegerValue(JPQLNode node) {
BigDecimal bigdec = new BigDecimal
(node.text.endsWith("l") || node.text.endsWith("L")
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java?rev=967240&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java Fri Jul 23 20:15:06 2010
@@ -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="WFulltimeEmployee")
+public class FulltimeEmployee extends Employee {
+ @Column(name="FTEmpProp1",length=10)
+ @Basic
+ private String ftEmpProp1;
+
+
+ @ManyToOne(optional=true,cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
+ @JoinColumn(name="Dept_No",referencedColumnName="OID")
+ @Index
+ private Department dept;
+
+ public FulltimeEmployee() {
+ }
+
+ public FulltimeEmployee(String desc) {
+ setDescription(desc);
+ }
+
+ public String getFTEmpProp1() {
+ return ftEmpProp1;
+ }
+
+ public void setFTEmpProp1(String ftEmpProp1) {
+ this.ftEmpProp1 = ftEmpProp1;
+ }
+
+ public Department getDept() {
+ return dept;
+ }
+
+ public void setDept(Department dept) {
+ this.dept = dept;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof FulltimeEmployee) {
+ FulltimeEmployee c = (FulltimeEmployee) other;
+ if (c.getOID() == this.getOID() &&
+ c.getDept() == this.getDept())
+ return true;
+ }
+ return false;
+ }
+}
+
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/FulltimeEmployee.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java?rev=967240&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java Fri Jul 23 20:15:06 2010
@@ -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="WParttimeEmployee")
+public class ParttimeEmployee extends Employee {
+ @Column(name="PTEmpProp1",length=10)
+ @Basic
+ private String ptEmpProp1;
+
+
+ @ManyToOne(optional=true,cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
+ @JoinColumn(name="Dept_No",referencedColumnName="OID")
+ @Index
+ private Department dept;
+
+ public ParttimeEmployee() {
+ }
+
+ public ParttimeEmployee(String desc) {
+ setDescription(desc);
+ }
+
+ public String getPTEmpProp1() {
+ return ptEmpProp1;
+ }
+
+ public void setPTEmpProp1(String ptEmpProp1) {
+ this.ptEmpProp1 = ptEmpProp1;
+ }
+
+ public Department getDept() {
+ return dept;
+ }
+
+ public void setDept(Department dept) {
+ this.dept = dept;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof ParttimeEmployee) {
+ ParttimeEmployee c = (ParttimeEmployee) other;
+ if (c.getOID() == this.getOID() &&
+ c.getDept() == this.getDept())
+ return true;
+ }
+ return false;
+ }
+}
+
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/ParttimeEmployee.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: 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=967240&r1=967239&r2=967240&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/TestInheritanceTypeJoinedQuery.java Fri Jul 23 20:15:06 2010
@@ -30,9 +30,13 @@ import org.apache.openjpa.persistence.te
public class TestInheritanceTypeJoinedQuery extends SQLListenerTestCase {
+ private int numPTEmployees = 1;
+ private int numFTEmployees = 2;
+ private int numContractors = 3;
public void setUp() {
setUp(Contractor.class, Employee.class, Department.class, Person.class,
+ FulltimeEmployee.class, ParttimeEmployee.class,
CLEAR_TABLES);
populate();
}
@@ -41,13 +45,25 @@ public class TestInheritanceTypeJoinedQu
EntityManager em = emf.createEntityManager();
Department d = new Department("IT");
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < numContractors; i++) {
Contractor c = new Contractor("ctr" + i);
c.setDept(d);
em.persist(c);
}
em.persist(d);
-
+
+ for (int i = 0; i < numFTEmployees; i++) {
+ FulltimeEmployee f = new FulltimeEmployee("ftemp" + i);
+ f.setDept(d);
+ em.persist(f);
+ }
+
+ for (int i = 0; i < numPTEmployees; i++) {
+ ParttimeEmployee p = new ParttimeEmployee("ptemp" + i);
+ p.setDept(d);
+ em.persist(p);
+ }
+
em.getTransaction().begin();
em.getTransaction().commit();
em.close();
@@ -57,16 +73,28 @@ public class TestInheritanceTypeJoinedQu
EntityManager em = emf.createEntityManager();
Query q = null;
String qS = null;
+ List rs = null;
+
+ qS = "SELECT p FROM Person p where TYPE(p) <> Contractor";
+ q = em.createQuery(qS);
+ rs = q.getResultList();
+ assertEquals(numPTEmployees + numFTEmployees, rs.size());
+ for (int i = 0; i < rs.size(); i++){
+ Object obj = rs.get(i);
+ assertTrue((obj instanceof ParttimeEmployee) || (obj instanceof FulltimeEmployee));
+ }
+
qS = "SELECT p FROM Person p where TYPE(p) = Contractor";
q = em.createQuery(qS);
- List rs = q.getResultList();
- assertEquals(3, rs.size());
+ rs = q.getResultList();
+ assertEquals(numContractors, rs.size());
for (int i = 0; i < rs.size(); i++)
assertTrue(rs.get(i) instanceof Contractor);
+
qS = "select p from Person p where TYPE(p) in (?1) order by p.name";
q = em.createQuery(qS).setParameter(1, Contractor.class);
rs = q.getResultList();
- assertEquals(3, rs.size());
+ assertEquals(numContractors, rs.size());
for (int i = 0; i < rs.size(); i++)
assertTrue(rs.get(i) instanceof Contractor);
@@ -82,6 +110,67 @@ public class TestInheritanceTypeJoinedQu
//System.out.println(e.getMessage());
}
+ qS = "SELECT p FROM Person p where TYPE(p) = Contractor AND p.name = 'Name ctr0'";
+ q = em.createQuery(qS);
+ rs = q.getResultList();
+ assertEquals(1, rs.size());
+ for (int i = 0; i < rs.size(); i++)
+ assertTrue(rs.get(i) instanceof Contractor);
+
+ qS = "select p from Person p where TYPE(p) in (?1, ?2) and p.name = ?3 order by p.name";
+ q = em.createQuery(qS);
+ q.setParameter(1, Contractor.class);
+ q.setParameter(2, FulltimeEmployee.class);
+ q.setParameter(3, "Name ctr0");
+
+ rs = q.getResultList();
+ assertEquals(1, rs.size());
+ for (int i = 0; i < rs.size(); i++) {
+ Object obj = rs.get(i);
+ assertTrue(obj instanceof Contractor || obj instanceof FulltimeEmployee);
+ }
+
+ qS = "select p from Person p where TYPE(p) in (?1, ?2) order by p.name";
+ q = em.createQuery(qS);
+ q.setParameter(1, Contractor.class);
+ q.setParameter(2, FulltimeEmployee.class);
+
+ rs = q.getResultList();
+ assertEquals(numContractors + numFTEmployees, rs.size());
+ for (int i = 0; i < rs.size(); i++) {
+ Object obj = rs.get(i);
+ assertTrue(obj instanceof Contractor || obj instanceof FulltimeEmployee);
+ }
+
+ qS = "select p from Person p where TYPE(p) not in (Contractor) order by p.name";
+ q = em.createQuery(qS);
+ rs = q.getResultList();
+ assertEquals(numPTEmployees + numFTEmployees, rs.size());
+ for (int i = 0; i < rs.size(); i++){
+ Object obj = rs.get(i);
+ assertTrue((obj instanceof ParttimeEmployee) || (obj instanceof FulltimeEmployee));
+ }
+
+ qS = "select p from Person p where TYPE(p) not in (?1) order by p.name";
+ q = em.createQuery(qS);
+ q.setParameter(1, Contractor.class);
+ rs = q.getResultList();
+ assertEquals(numPTEmployees + numFTEmployees, rs.size());
+ for (int i = 0; i < rs.size(); i++){
+ Object obj = rs.get(i);
+ assertTrue((obj instanceof ParttimeEmployee) || (obj instanceof FulltimeEmployee));
+ }
+
+ qS = "select p from Person p where TYPE(p) not in (?1, ?2) order by p.name";
+ q = em.createQuery(qS);
+ q.setParameter(1, Contractor.class);
+ q.setParameter(2, FulltimeEmployee.class);
+ rs = q.getResultList();
+ assertEquals(numPTEmployees, rs.size());
+ for (int i = 0; i < rs.size(); i++){
+ Object obj = rs.get(i);
+ assertTrue((obj instanceof ParttimeEmployee) || (obj instanceof FulltimeEmployee));
+ }
}
public void testInheritanceTypeJoinedQuery() {
@@ -183,8 +272,10 @@ public class TestInheritanceTypeJoinedQu
qS = "SELECT p FROM Person p ";
q = em.createQuery(qS);
- for (Object aResult: (List<Object>) q.getResultList()) {
- assertTrue(aResult instanceof Contractor);
+ List rs = (List<Object>) q.getResultList();
+ assertEquals(numPTEmployees + numFTEmployees + numContractors, rs.size());
+ for (Object aResult: rs) {
+ assertTrue(aResult instanceof Person);
}
em.close();