Author: mikedd
Date: Mon May 3 15:59:48 2010
New Revision: 940491
URL: http://svn.apache.org/viewvc?rev=940491&view=rev
Log:
OPENJPA-1483: Support count distinct compound key
Submitted By: Heath Thomann, merged from Fay Wang's changes in trunk
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java
(with props)
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java
(with props)
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java
(with props)
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java
(with props)
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java
(with props)
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Count.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Distinct.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
openjpa/branches/1.2.x/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Count.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Count.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Count.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Count.java
Mon May 3 15:59:48 2010
@@ -18,6 +18,7 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
+import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
@@ -29,16 +30,30 @@ import org.apache.openjpa.jdbc.sql.SQLBu
class Count
extends UnaryOp {
+ private boolean isCountMultiColumns = false;
+ private boolean isCountDistinct = false;
+
/**
* Constructor. Provide the value to operate on.
*/
public Count(Val val) {
super(val);
+ if (val instanceof Distinct)
+ isCountDistinct = true;
}
public ExpState initialize(Select sel, ExpContext ctx, int flags) {
// join into related object if present
- return initializeValue(sel, ctx, JOIN_REL);
+ ExpState expState = initializeValue(sel, ctx, JOIN_REL);
+ Val val = isCountDistinct ? ((Distinct)getValue()).getValue() :
getValue();
+ if (val instanceof PCPath) {
+ Column[] cols = ((PCPath)val).getColumns(expState);
+ if (cols.length > 1) {
+ isCountMultiColumns = true;
+ }
+ }
+
+ return expState;
}
protected Class getType(Class c) {
@@ -53,14 +68,24 @@ class Count
return true;
}
+ public boolean isCountDistinctMultiCols() {
+ return isCountDistinct && isCountMultiColumns;
+ }
+
/**
* Overrides SQL formation by replacing COUNT(column) by COUNT(*) when
specific conditions are met and DBDictionary
* configuration <code>useWildCardForCount</code> is set.
*/
@Override
public void appendTo(Select sel, ExpContext ctx, ExpState state, SQLBuffer
sql, int index) {
- super.appendTo(sel, ctx, state, sql, index);
- if (ctx.store.getDBDictionary().useWildCardForCount &&
state.joins.isEmpty()) {
+ if (isCountDistinctMultiCols()) {
+ getValue().appendTo(sel, ctx, state, sql, 0);
+ sql.addCastForParam(getOperator(), getValue());
+ } else {
+ super.appendTo(sel, ctx, state, sql, index);
+ }
+ if ((ctx.store.getDBDictionary().useWildCardForCount &&
state.joins.isEmpty()) ||
+ !isCountDistinct && isCountMultiColumns){
String s = sql.getSQL();
if (s.startsWith("COUNT(") && s.endsWith(")")) {
sql.replaceSqlString("COUNT(".length(), s.length() - 1, "*");
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Distinct.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Distinct.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Distinct.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Distinct.java
Mon May 3 15:59:48 2010
@@ -41,4 +41,22 @@ class Distinct
protected String getOperator() {
return "DISTINCT";
}
+
+ @Override
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql, int index) {
+ Val val = getValue();
+ if (val instanceof PCPath) {
+ boolean noParen = getNoParen();
+ sql.append(getOperator());
+ sql.append(noParen ? " " : "(");
+ ((PCPath)val).appendTo(sel, ctx, state, sql);
+ sql.addCastForParam(getOperator(), val);
+ if (!noParen)
+ sql.append(")");
+
+ } else
+ super.appendTo(sel, ctx, state, sql, index);
+ }
+
}
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
Mon May 3 15:59:48 2010
@@ -716,20 +716,33 @@ public class PCPath
return getColumns(state).length;
}
- public void appendTo(Select sel, ExpContext ctx, ExpState state,
- SQLBuffer sql, int index) {
- Column col = getColumns(state)[index];
-
- // if select is null, it means we are not aliasing columns
- // (e.g., during a bulk update)
- if (sel == null)
- sql.append(col.getName());
- else if (_type == XPATH)
- // if this is an xpath, append xpath string
- sql.append(getXPath());
- else
- sql.append(sel.getColumnAlias(col, state.joins));
- }
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql) {
+ Column[] cols = getColumns(state);
+ for (int i = 0; i < cols.length; i++) {
+ appendTo(sel, state, sql, cols[i]);
+ if (i < cols.length - 1)
+ sql.append(", ");
+ }
+ }
+
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql, int index) {
+ Column col = getColumns(state)[index];
+ appendTo(sel, state, sql, col);
+ }
+
+ public void appendTo(Select sel, ExpState state, SQLBuffer sql, Column
col) {
+ // if select is null, it means we are not aliasing columns
+ // (e.g., during a bulk update)
+ if (sel == null)
+ sql.append(col.getName());
+ else if (_type == XPATH)
+ // if this is an xpath, append xpath string
+ sql.append(getXPath());
+ else
+ sql.append(sel.getColumnAlias(col, state.joins));
+ }
public void appendIsEmpty(Select sel, ExpContext ctx, ExpState state,
SQLBuffer sql) {
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SelectConstructor.java
Mon May 3 15:59:48 2010
@@ -32,6 +32,8 @@ import org.apache.openjpa.kernel.exps.Co
import org.apache.openjpa.kernel.exps.Expression;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UnsupportedException;
/**
* Turns parsed queries into selects.
@@ -43,6 +45,7 @@ public class SelectConstructor
implements Serializable {
private boolean _extent = false;
+ private static final Localizer _loc =
Localizer.forPackage(SelectConstructor.class);
/**
* Return true if we know the select to have on criteria; to be an extent.
@@ -106,6 +109,18 @@ public class SelectConstructor
}
for (int i = 0; i < exps.grouping.length; i++)
((Val) exps.grouping[i]).groupBy(sel, ctx, state.grouping[i]);
+
+ if (exps.projections.length == 1) {
+ Val val = (Val) exps.projections[0];
+ if (val instanceof Count &&
((Count)val).isCountDistinctMultiCols()) {
+ Select newSel = ctx.store.getSQLFactory().newSelect();
+ newSel.select("COUNT(*)", val);
+ newSel.setExpectedResultCount(1, true);
+ newSel.setFromSelect(sel);
+ sel.setExpectedResultCount(0, true);
+ sel = newSel;
+ }
+ }
return sel;
}
@@ -198,6 +213,10 @@ public class SelectConstructor
// projections; this ensures that we have all our joins cached
state.projections[i] = resultVal.initialize(sel, ctx,
Val.JOIN_REL | Val.FORCE_OUTER);
+ if (exps.projections.length > 1 && resultVal instanceof Count)
{
+ if (((Count)resultVal).isCountDistinctMultiCols())
+ throw new
UnsupportedException(_loc.get("count-distinct-multi-col-only"));
+ }
joins = sel.and(joins, state.projections[i].joins);
}
}
@@ -253,6 +272,8 @@ public class SelectConstructor
Select inner = sel.getFromSelect();
Val val;
Joins joins = null;
+ boolean isCountDistinctMultiCols = false;
+
if (sel.getSubselectPath() != null)
joins = sel.newJoins().setSubselect(sel.getSubselectPath());
@@ -270,9 +291,18 @@ public class SelectConstructor
// subselect for objects; we really just need the primary key
values
sel.select(mapping.getPrimaryKeyColumns(), joins);
} else {
+ if (exps.projections.length == 1) {
+ val = (Val) exps.projections[0];
+ if (val instanceof Count &&
((Count)val).isCountDistinctMultiCols()) {
+ isCountDistinctMultiCols = true;
+ if (sel.getParent() != null)
+ throw new
UnsupportedException(_loc.get("count-distinct-multi-col-subselect-unsupported"));
+ }
+ }
+
// if we have an inner select, we need to select the candidate
// class' pk columns to guarantee unique instances
- if (inner != null)
+ if (inner != null && !isCountDistinctMultiCols)
inner.select(mapping.getPrimaryKeyColumns(), joins);
// select each result value; no need to pass on the eager mode
since
@@ -280,9 +310,13 @@ public class SelectConstructor
boolean pks = sel.getParent() != null;
for (int i = 0; i < exps.projections.length; i++) {
val = (Val) exps.projections[i];
- if (inner != null)
- val.selectColumns(inner, ctx, state.projections[i], pks);
- val.select(sel, ctx, state.projections[i], pks);
+ if (inner != null) {
+ if (!isCountDistinctMultiCols)
+ val.selectColumns(inner, ctx, state.projections[i],
pks);
+ else
+ val.select(inner, ctx, state.projections[i], pks);
+ } else
+ val.select(sel, ctx, state.projections[i], pks);
}
// make sure having columns are selected since it is required by
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
Mon May 3 15:59:48 2010
@@ -74,6 +74,10 @@ abstract class UnaryOp
public void setImplicitType(Class type) {
_cast = type;
}
+
+ public boolean getNoParen() {
+ return _noParen;
+ }
public ExpState initialize(Select sel, ExpContext ctx, int flags) {
return initializeValue(sel, ctx, flags);
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
Mon May 3 15:59:48 2010
@@ -3041,10 +3041,13 @@ public class SelectImpl
alias = alias + _dict.getStringVal;
String as = null;
- if (inner)
- as = ((String) alias).replace('.', '_');
- else if (_selectAs != null)
- as = (String) _selectAs.get(id);
+ if (inner) {
+ if (alias instanceof String){
+ as = ((String)
alias).replace('.', '_');
+ }
+ } else if (_selectAs != null){
+ as = (String) _selectAs.get(id);
+ }
if (as != null) {
if (ident && _idents != null)
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties?rev=940491&r1=940490&r2=940491&view=diff
==============================================================================
---
openjpa/branches/1.2.x/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
(original)
+++
openjpa/branches/1.2.x/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
Mon May 3 15:59:48 2010
@@ -120,3 +120,8 @@ error-setting-query-timeout: A SQLExcept
continue processing. If this is a benign error you may disable it entirely
\
by setting the supportsQueryTimeout attribute on the DBDictionary to
false.\
The exception thrown was {1}.
+empty-collection-parm: Input parameter "{0}" is empty.
+count-distinct-multi-col-only: Count distinct compound primary key is not \
+ supported when there are other projection items.
+count-distinct-multi-col-subselect-unsupported: Count distinct multiple
columns \
+ in the subselect is not supported.
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java?rev=940491&view=auto
==============================================================================
---
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java
(added)
+++
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java
Mon May 3 15:59:48 2010
@@ -0,0 +1,67 @@
+/*
+ * 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.enhance.identity;
+
+import javax.persistence.*;
+
+...@entity
+...@table(name="DEP2_MBI")
+public class Dependent {
+ @EmbeddedId
+ DependentId id;
+
+ @ManyToOne Employee emp;
+
+ public Employee getEmp() {
+ return emp;
+ }
+
+ public void setEmp(Employee emp) {
+ this.emp = emp;
+ }
+
+ public DependentId getId() {
+ return id;
+ }
+
+ public void setId(DependentId id) {
+ this.id = id;
+ }
+
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (!(o instanceof Dependent)) return false;
+ Dependent d0 = (Dependent)o;
+ DependentId id0 = d0.getId();
+ if (id == null && id0 != null) return false;
+ if (!id.equals(id0)) return false;
+ Employee e0 = d0.getEmp();
+ if (emp != null && !emp.equals(e0)) return false;
+ if (emp == null && e0 != null) return false;
+ return true;
+ }
+
+ public int hashCode() {
+ int ret = 0;
+ ret = ret * 31 + id.hashCode();
+ ret = ret * 31 + emp.hashCode();
+ return ret;
+ }
+
+}
Propchange:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Dependent.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java?rev=940491&view=auto
==============================================================================
---
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java
(added)
+++
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java
Mon May 3 15:59:48 2010
@@ -0,0 +1,65 @@
+/*
+ * 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.enhance.identity;
+
+import javax.persistence.*;
+
+...@embeddable
+public class DependentId {
+ String name;
+
+ public DependentId() {}
+
+ public DependentId(String name, EmployeeId empPK) {
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 :
name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ DependentId other = (DependentId) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+}
Propchange:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/DependentId.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java?rev=940491&view=auto
==============================================================================
---
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java
(added)
+++
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java
Mon May 3 15:59:48 2010
@@ -0,0 +1,79 @@
+/*
+ * 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.enhance.identity;
+
+import javax.persistence.*;
+
+import java.util.*;
+
+...@entity
+...@table(name="EMP2_MBI")
+public class Employee {
+ @EmbeddedId
+ EmployeeId empId;
+
+ @OneToMany(mappedBy="emp")
+ List<Dependent> dependents = new ArrayList<Dependent>();
+
+ public EmployeeId getEmpId() {
+ return empId;
+ }
+
+ public void setEmpId(EmployeeId empId) {
+ this.empId = empId;
+ }
+
+ public List<Dependent> getDependents() {
+ return dependents;
+ }
+
+ public void setDependents(List<Dependent> dependents) {
+ this.dependents = dependents;
+ }
+
+ public void addDependent(Dependent d) {
+ dependents.add(d);
+ }
+
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (!(o instanceof Employee)) return false;
+ Employee e0 = (Employee)o;
+ EmployeeId eid0 = e0.getEmpId();
+ List<Dependent> ds0 = e0.getDependents();
+ if (!empId.equals(eid0)) return false;
+ if (ds0 != null && ds0.size() != 0 && dependents == null) return
false;
+ if (ds0 == null && dependents != null && dependents.size() != 0)
+ return false;
+ if (ds0 == null && dependents == null) return true;
+ if (ds0 != null && dependents != null) {
+ if (ds0.size() != dependents.size()) return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ int ret = 0;
+ ret = ret * 31 + empId.hashCode();
+ for (Dependent d : dependents) {
+ ret = ret * 31 +d.id.hashCode();
+ }
+ return ret;
+ }
+}
Propchange:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/Employee.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java?rev=940491&view=auto
==============================================================================
---
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java
(added)
+++
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java
Mon May 3 15:59:48 2010
@@ -0,0 +1,71 @@
+/*
+ * 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.enhance.identity;
+
+import javax.persistence.*;
+
+...@embeddable
+public class EmployeeId {
+ String firstName;
+ String lastName;
+
+ public EmployeeId() {}
+
+ public EmployeeId(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (!(o instanceof EmployeeId)) return false;
+ EmployeeId eid = (EmployeeId)o;
+ String firstName0 = eid.getFirstName();
+ String lastName0 = eid.getLastName();
+ if (firstName != null && !firstName.equals(firstName0)) return false;
+ if (firstName == null && firstName0 != null) return false;
+ if (lastName != null && !lastName.equals(lastName0)) return false;
+ if (lastName == null && lastName0 != null) return false;
+ return true;
+ }
+
+ public int hashCode() {
+ int ret = 0;
+ ret = ret * 31 + firstName.hashCode();
+ ret = ret * 31 + lastName.hashCode();
+ return ret;
+ }
+
+}
Propchange:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/EmployeeId.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java
URL:
http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java?rev=940491&view=auto
==============================================================================
---
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java
(added)
+++
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java
Mon May 3 15:59:48 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.enhance.identity;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestCountDistinctMultiCols extends SingleEMFTestCase {
+
+ public void setUp() throws Exception {
+
super.setUp(DROP_TABLES,Employee.class,EmployeeId.class,Dependent.class,DependentId.class);
+ }
+
+ public void testCountDistinctMultiCols() {
+ EntityManager em = emf.createEntityManager();
+
+ Employee emp1 = new Employee();
+ EmployeeId empId1 = new EmployeeId();
+ empId1.setFirstName("James");
+ empId1.setLastName("Bond");
+ emp1.setEmpId(empId1);
+
+ Employee emp2 = new Employee();
+ EmployeeId empId2 = new EmployeeId();
+ empId2.setFirstName("James");
+ empId2.setLastName("Obama");
+ emp2.setEmpId(empId2);
+
+ Dependent dep1 = new Dependent();
+ DependentId depId1 = new DependentId();
+ dep1.setEmp(emp1);
+ depId1.setName("Alan");
+ dep1.setId(depId1);
+
+ Dependent dep2 = new Dependent();
+ DependentId depId2 = new DependentId();
+ dep2.setEmp(emp2);
+ depId2.setName("Darren");
+ dep2.setId(depId2);
+
+ em.persist(emp1);
+ em.persist(emp2);
+ em.persist(dep1);
+ em.persist(dep2);
+
+ em.getTransaction().begin();
+ em.flush();
+ em.getTransaction().commit();
+
+ String[] jpqls = {
+ "SELECT COUNT (DISTINCT d2.emp) FROM Dependent d2",
+ "SELECT COUNT (DISTINCT e2.dependents) FROM Employee e2",
+ "select count (DISTINCT d2) from Dependent d2",
+ };
+
+ for (int i = 0; i < jpqls.length; i++) {
+ Query q = em.createQuery(jpqls[i]) ;
+ Long o = (Long)q.getSingleResult();
+ int count = (int)o.longValue();
+ assertEquals(2, count);
+ }
+ }
+}
Propchange:
openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/identity/TestCountDistinctMultiCols.java
------------------------------------------------------------------------------
svn:eol-style = native