You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2016/06/24 03:43:49 UTC
svn commit: r1750039 - in /openjpa/branches/2.2.1.x: ./
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed...
Author: hthomann
Date: Fri Jun 24 03:43:49 2016
New Revision: 1750039
URL: http://svn.apache.org/viewvc?rev=1750039&view=rev
Log:
OPENJPA-2631: Fix for CriteriaBuilder issue with an @EmbeddedId that contains more than one field. Ported 2.1.x commit to 2.2.1
Added:
openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/
- copied from r1750036, openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/
Modified:
openjpa/branches/2.2.1.x/ (props changed)
openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java
openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java
openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
Propchange: openjpa/branches/2.2.1.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jun 24 03:43:49 2016
@@ -1,5 +1,5 @@
/openjpa/branches/1.0.x:736493
/openjpa/branches/2.0.x:1419659,1484136,1484287,1504611
-/openjpa/branches/2.1.x:1415379,1415398,1436150,1469090,1469949,1484300,1484313,1485010,1505837,1513249,1517838,1529241,1530146,1533218,1533280,1539188,1569528,1575444,1591536,1614935,1636464,1648430,1655218,1662610,1673300,1673491,1686894,1709201,1709309
+/openjpa/branches/2.1.x:1415379,1415398,1436150,1469090,1469949,1484300,1484313,1485010,1505837,1513249,1517838,1529241,1530146,1533218,1533280,1539188,1569528,1575444,1591536,1614935,1636464,1648430,1655218,1662610,1673300,1673491,1686894,1709201,1709309,1750036
/openjpa/branches/2.2.x:1580898,1580939,1591681,1641906,1642555,1702143
/openjpa/trunk:1416742,1420324,1430117,1431649,1436957,1436960,1448662,1448796,1451369,1456574,1456614,1459091,1461833,1469646,1469649,1469652,1504282,1564989,1600757,1603251
Modified: openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java?rev=1750039&r1=1750038&r2=1750039&view=diff
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java (original)
+++ openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java Fri Jun 24 03:43:49 2016
@@ -18,6 +18,10 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
+import java.util.List;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
@@ -62,8 +66,31 @@ class EqualExpression
new FilterValueImpl(sel, ctx, bstate.state1, val1),
new FilterValueImpl(sel, ctx, bstate.state2, val2));
} else {
- int len = java.lang.Math.min(val1.length(sel, ctx,
- bstate.state1), val2.length(sel, ctx, bstate.state2));
+ int lenVal1 = val1.length(sel, ctx, bstate.state1);
+ int lenVal2 = val2.length(sel, ctx, bstate.state2);
+ int len = java.lang.Math.min(lenVal1, lenVal2);
+
+ // OPENJPA-2631: Detect and handle slightly differently the
+ // case where a composite PK is in use. When an equals comparison
+ // is created by CriteriaBuilder, and the comparison is done against
+ // an entity with a composite PK, 'val2' can be either a:
+ // 1) Lit - in this case a Lit is hard coded to return a length of 1.
+ // 2) Param - in this case the metadata is null so length will return 1.
+ // Given this, first look to see if lenVal1 is greater than lenVal2.
+ if (lenVal1 > lenVal2) {
+ // If here, lets get the metadata from val1 and see if its PK
+ // is an embeddable. If so, the length (val1Len) will be the
+ // size of the number of colunns in the PK. Use this length
+ // in order to create an equal expression with the right number
+ // of 'AND' statementes.
+ ClassMapping cm = (ClassMapping) val1.getMetaData();
+ FieldMapping[] fmsPK = cm.getPrimaryKeyFieldMappings();
+
+ if (fmsPK[0].isEmbedded()) {
+ len = lenVal1;
+ }
+ }
+
for (int i = 0; i < len; i++) {
if (i > 0)
buf.append(" AND ");
Modified: openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java?rev=1750039&r1=1750038&r2=1750039&view=diff
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java (original)
+++ openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java Fri Jun 24 03:43:49 2016
@@ -116,10 +116,11 @@ public class Lit
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer sql, int index) {
LitExpState lstate = (LitExpState) state;
- if (lstate.otherLength > 1)
- sql.appendValue(((Object[]) lstate.sqlValue)[index],
- lstate.getColumn(index));
- else if (_isRaw) {
+ if (lstate.otherLength > 1) {
+ sql.appendValue(((Object[]) lstate.sqlValue)[index], lstate.getColumn(index));
+ // OPENJPA-2631: Return so as not to go into sql.appendValue a second time below.
+ return;
+ } else if (_isRaw) {
int parseType = getParseType();
if (parseType == Literal.TYPE_ENUM) {
StringBuilder value = new StringBuilder();
Modified: openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java?rev=1750039&r1=1750038&r2=1750039&view=diff
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (original)
+++ openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java Fri Jun 24 03:43:49 2016
@@ -253,6 +253,32 @@ public class ClassMapping
sm = (OpenJPAStateManager) pc.pcGetStateManager();
if (sm == null) {
ret = getValueFromUnmanagedInstance(obj, cols, true);
+
+ // OPENJPA-2631 start
+ // Check to see if we are dealing with a Embeddable pk. If the PK is an Embeddable, AND IFF the
+ // columns in the Embeddable are greater than 1, we are dealing with a composite primary
+ // key, and as such 'ret' will be an instance of the embeddable, NOT the individual PK values.
+ // Given this, we need to dig deeper and get the individual values of the embeddable key.
+ // On the other hand, if the embeddable only contains one column, 'ret' will be the value of
+ // that column and as such no further digging is necessary.
+ FieldMapping[] fmsPK = this.getPrimaryKeyFieldMappings();
+ List<FieldMapping> fms = getFieldMappings(cols, true);
+
+ // Note that if we are dealing with an embeddable that is an EmbeddableId, the fms.size will
+ // always be 1 (since an EmbeddableId is slightly opaque, we don't have an fms for each field).
+ // If on the other hand we are dealing with an embeddable that is an @IdClass, fms.size will be the
+ // number columns in the @IdClass. Furthermore, when dealing with @IdClass, 'ret' will already
+ // properly contain the column values, therefore no further processing is needed.
+ if (fmsPK[0].isEmbedded() && cols.length > 1 && fms.size() == 1) {
+ // OK, we know this PK is an embeddable. So get the individual field values.
+ Object[] tmpRet = new Object[cols.length];
+ for (int i = 0; i < cols.length; i++) {
+ Joinable join = this.assertJoinable(cols[i]);
+ tmpRet[i] = join.getJoinValue(ret, cols[i], store);
+ }
+ ret = tmpRet;
+ }
+ // OPENJPA-2631 end
} else if (sm.isDetached()) {
obj = store.getContext().find(sm.getObjectId(), false, null);
sm = store.getContext().getStateManager(obj);