Author: hthomann Date: Fri Jun 24 03:28:06 2016 New Revision: 1750036 URL: http://svn.apache.org/viewvc?rev=1750036&view=rev Log: OPENJPA-2631: Fix for CriteriaBuilder issue with an @EmbeddedId that contains more than one field.
Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java (with props) openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java (with props) Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java Modified: openjpa/branches/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.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java?rev=1750036&r1=1750035&r2=1750036&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java Fri Jun 24 03:28:06 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.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java?rev=1750036&r1=1750035&r2=1750036&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java Fri Jun 24 03:28:06 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.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java?rev=1750036&r1=1750035&r2=1750036&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMapping.java Fri Jun 24 03:28:06 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); Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java Fri Jun 24 03:28:06 2016 @@ -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.embed.compositepk; + +import java.io.Serializable; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table(name = "SUBJECT") +public class Subject implements Serializable { + + private static final long serialVersionUID = -2529380440548731281L; + + @EmbeddedId + private SubjectKey key; + + public Subject() { + } + + public SubjectKey getKey() { + return key; + } + + public void setKey(SubjectKey key) { + this.key = key; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.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; + Subject other = (Subject) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + return true; + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.persistence.embed.compositepk; + +import java.io.Serializable; + +public class SubjectIdClass implements Serializable { + + private Integer subjectNummer; + + private String subjectTypeCode; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((subjectNummer == null) ? 0 : subjectNummer.hashCode()); + result = prime * result + ((subjectTypeCode == null) ? 0 : subjectTypeCode.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; + SubjectIdClass other = (SubjectIdClass) obj; + if (subjectNummer == null) { + if (other.subjectNummer != null) + return false; + } else if (!subjectNummer.equals(other.subjectNummer)) + return false; + if (subjectTypeCode == null) { + if (other.subjectTypeCode != null) + return false; + } else if (!subjectTypeCode.equals(other.subjectTypeCode)) + return false; + return true; + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectIdClass.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,91 @@ +/* + * 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.embed.compositepk; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class SubjectKey implements Serializable { + private static final long serialVersionUID = 3714506425307136262L; + + @Column(name = "SUBJECTNUMMER") + private Integer subjectNummer; + + @Column(name = "CODE_SUBJECTTYPE") + private String subjectTypeCode; + + public SubjectKey() { + super(); + } + + public SubjectKey(Integer subjectNummer, String subjectTypeCode) { + this.subjectNummer = subjectNummer; + this.subjectTypeCode = subjectTypeCode; + } + + public Integer getSubjectNummer() { + return subjectNummer; + } + + public void setSubjectNummer(Integer subjectNummer) { + this.subjectNummer = subjectNummer; + } + + public String getSubjectTypeCode() { + return subjectTypeCode; + } + + public void setSubjectType(String subjectType) { + this.subjectTypeCode = subjectType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((subjectNummer == null) ? 0 : subjectNummer.hashCode()); + result = prime * result + ((subjectTypeCode == null) ? 0 : subjectTypeCode.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; + SubjectKey other = (SubjectKey) obj; + if (subjectNummer == null) { + if (other.subjectNummer != null) + return false; + } else if (!subjectNummer.equals(other.subjectNummer)) + return false; + if (subjectTypeCode == null) { + if (other.subjectTypeCode != null) + return false; + } else if (!subjectTypeCode.equals(other.subjectTypeCode)) + return false; + return true; + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,30 @@ +/* + * 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.embed.compositepk; + +import javax.persistence.metamodel.SingularAttribute; + +@javax.persistence.metamodel.StaticMetamodel +(value=org.apache.openjpa.persistence.embed.compositepk.SubjectKey.class) +@javax.annotation.Generated +(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Feb 05 14:31:20 MST 2016") +public class SubjectKey_ { + public static volatile SingularAttribute<SubjectKey,Integer> subjectNummer; + public static volatile SingularAttribute<SubjectKey,String> subjectTypeCode; +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectKey_.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,95 @@ +/* + * 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.embed.compositepk; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.Table; + +@Entity +@Table(name = "SUBJECT2") +@IdClass(SubjectIdClass.class) +public class SubjectWithIdClass implements Serializable { + + private static final long serialVersionUID = 8038887700493762410L; + + @Id + @Column(name = "SUBJECTNUMMER") + private Integer subjectNummer; + + @Id + @Column(name = "CODE_SUBJECTTYPE") + private String subjectTypeCode; + + public SubjectWithIdClass() { + } + + public void setSubjectNummer(Integer subjectNummer) { + this.subjectNummer = subjectNummer; + + } + + public Integer getSubjectNummer() { + return subjectNummer; + } + + public void setSubjectTypeCode(String subjectTypeCode) { + this.subjectTypeCode = subjectTypeCode; + + } + + public String getSubjectTypeCode() { + return subjectTypeCode; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((subjectNummer == null) ? 0 : subjectNummer.hashCode()); + result = prime * result + ((subjectTypeCode == null) ? 0 : subjectTypeCode.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; + SubjectWithIdClass other = (SubjectWithIdClass) obj; + if (subjectNummer == null) { + if (other.subjectNummer != null) + return false; + } else if (!subjectNummer.equals(other.subjectNummer)) + return false; + if (subjectTypeCode == null) { + if (other.subjectTypeCode != null) + return false; + } else if (!subjectTypeCode.equals(other.subjectTypeCode)) + return false; + return true; + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,30 @@ +/* + * 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.embed.compositepk; + +import javax.persistence.metamodel.SingularAttribute; + +@javax.persistence.metamodel.StaticMetamodel +(value=org.apache.openjpa.persistence.embed.compositepk.SubjectWithIdClass.class) +@javax.annotation.Generated +(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Feb 05 14:31:20 MST 2016") +public class SubjectWithIdClass_ { + public static volatile SingularAttribute<SubjectWithIdClass,Integer> subjectNummer; + public static volatile SingularAttribute<SubjectWithIdClass,String> subjectTypeCode; +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/SubjectWithIdClass_.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,29 @@ +/* + * 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.embed.compositepk; + +import javax.persistence.metamodel.SingularAttribute; + +@javax.persistence.metamodel.StaticMetamodel +(value=org.apache.openjpa.persistence.embed.compositepk.Subject.class) +@javax.annotation.Generated +(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Feb 05 14:31:20 MST 2016") +public class Subject_ { + public static volatile SingularAttribute<Subject,SubjectKey> key; +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Subject_.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,538 @@ +/* + * 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.embed.compositepk; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityTransaction; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.ParameterExpression; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import junit.framework.Assert; + +import org.apache.openjpa.persistence.test.SingleEMFTestCase; + +public class TestCompositePrimaryKeys extends SingleEMFTestCase { + + // NOTE: There are 3 aspects to the fix to OPENJPA-2631, each being tested in some manner in the test + // methods below. The 3 aspects of the fix are: + // + // 1) Fix in ClassMapping which resolves the reported ClassCastEx. + // 2) After #1, things progressed further, but for some CriteriaBuilder tests incorrect SQL was created as follows: + // 2.1) An equals expression was created for only one of the columns in the composite PK. To + // resolve this a fix was made to class EqualExpression. + // 2.2) An extra parameter marker (?) was added to the SQL. To resolve this a fix was made to class Lit. + + protected EntityManager em; + private EntityTransaction tx; + + public void setUp() { + super.setUp(DROP_TABLES, Subject.class, SubjectKey.class, SubjectWithIdClass.class, Topic.class); + + em = emf.createEntityManager(); + tx = em.getTransaction(); + tx.begin(); + createData(); + } + + /* + * OpenJPA handles this test just fine with or without the fixes of OPENJPA-2631. + */ + public void testFindUsingFindOnSubjectKey() { + + Subject s = createSubject(); + + Subject s2 = em.find(Subject.class, s.getKey()); + + verifySubject(s, s2); + } + + /* + * OpenJPA handles this test just fine with or without the fixes of OPENJPA-2631. This works, + * compared to other tests, because a select is performed on the key class' fields. + */ + public void testFindUsingEqualsOnObjectJPQL() { + Subject s = createSubject(); + + TypedQuery<Subject> query = em.createQuery("select distinct s from Subject s where " + + "s.key.subjectNummer = :subjectNummer AND s.key.subjectTypeCode = " + + ":subjectTypeCode", Subject.class); + query.setParameter("subjectNummer", s.getKey().getSubjectNummer()); + query.setParameter("subjectTypeCode", s.getKey().getSubjectTypeCode()); + + Subject s2 = query.getSingleResult(); + + verifySubject(s, s2); + } + + /* + * Just like the previous test, OpenJPA handles this test just fine with or without the + * fixes of OPENJPA-2631. This works, compared to other tests, because a select is + * performed on the key class' fields. This slight difference in this test compared to the + * previous test is that it traverses from Topic to the SubjectKey fields. + */ + public void testFindUsingJPQLEqualsOnSubjectKeyAttributes() { + + Subject s = createSubject(); + + TypedQuery<Topic> query = em.createQuery("select distinct t from Topic t where t.subject.key.subjectNummer = " + + ":subjectNummer AND t.subject.key.subjectTypeCode = :subjectTypeCode", Topic.class); + query.setParameter("subjectNummer", s.getKey().getSubjectNummer()); + query.setParameter("subjectTypeCode", s.getKey().getSubjectTypeCode()); + Topic topic = query.getSingleResult(); + + verifyResults(topic, s); + } + + /* + * This test results in an EXPECTED exception: + * + * ArgumentException: An error occurred while parsing the query filter 'select distinct g from Topic g where + * t.subject.key = :subjectKey'. Error message: JPQL query does not support conditional expression over embeddable + * class. JPQL string: "key". + * + * The message in the exception tells it all. Per the spec, you can not do a compare on embeddables. + */ + public void testFindUsingJPQLEqualsOnSubjectKey() { + try { + em.createQuery("select distinct t from Topic t where t.subject.key = :subjectKey"); + } catch (Throwable t) { + // An exception is EXPECTED! + Assert.assertTrue(t.getMessage().contains("does not support conditional expression")); + } + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey cannot be cast to + * [Ljava.lang.Object;] + * at org.apache.openjpa.jdbc.kernel.exps.Param.appendTo(Param.java:149) + * + * With fix #1, this test works fine. + */ + public void testFindSubjectUsingJPQLEqualsOnSubject() { + + Subject s = createSubject(); + + TypedQuery<Subject> query = em.createQuery("select s from Subject s where s = :subject", Subject.class); + query.setParameter("subject", s); + Subject s2 = query.getSingleResult(); + + verifySubject(s, s2); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey cannot be cast to + * [Ljava.lang.Object;] + * at org.apache.openjpa.jdbc.kernel.exps.Param.appendTo(Param.java:149) + * + * With fix #1, this test works fine. + */ + public void testFindUsingNamedQuery() { + + Subject s = createSubject(); + + TypedQuery<Topic> q = em.createNamedQuery("bySubject", Topic.class); + + q.setParameter("subject", s); + + Topic topic = q.getSingleResult(); + + verifyResults(topic, s); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey cannot be cast to + * [Ljava.lang.Object;] + * at org.apache.openjpa.jdbc.kernel.exps.Param.appendTo(Param.java:149) + * + * With fix #1, this test works fine. + */ + public void testFindUsingJPQLEqualsOnSubject() { + + Subject s = createSubject(); + + TypedQuery<Topic> query = + em.createQuery("select distinct t from Topic t where t.subject = :subject", Topic.class); + query.setParameter("subject", s); + Topic topic = query.getSingleResult(); + + verifyResults(topic, s); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey cannot be cast to + * [Ljava.lang.Object;] + * at org.apache.openjpa.jdbc.kernel.exps.Param.appendTo(Param.java:149) + * + * With fix #1, the CCEx is avoided/resolved. However, we then got an incorrectly generated SQL as follows: + * + * SELECT t0.SUBJECTNUMMER, t0.CODE_SUBJECTTYPE FROM SUBJECT t0 WHERE (t0.SUBJECTNUMMER = ?) + * optimize for 1 row [params=(int) 1] + * + * Notice that 't0.CODE_SUBJECTTYPE' is missing. With fix #2.1 this issue is resolved. + * + * The thing to note (which is different than the test 'findSubjectUsingCriteriaBuilderEquals' below) is that + * the Subject is treated as an OpenJPA 'Parameter' (see changes in EqualExpression). The test + * 'findSubjectUsingCriteriaBuilderEquals' below causes the Subject to be treated as a Lit. There is + * a bug in both cases, with an additional bug for the 'Lit' case. + */ + public void testFindSubjectUsingCriteriaBuilderEqualsAndParameter() { + + Subject s = createSubject(); + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<Subject> cq = builder.createQuery(Subject.class); + + Root<Subject> subjectRoot = cq.from(Subject.class); + cq.select(subjectRoot); + + ParameterExpression<Subject> param1 = builder.parameter(Subject.class, "subject"); + Predicate subjectPredicate = builder.equal(subjectRoot, param1); + + cq.where(subjectPredicate); + + TypedQuery<Subject> query = em.createQuery(cq); + query.setParameter("subject", s); + + Subject s2 = query.getSingleResult(); + + verifySubject(s, s2); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * Caused by: java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey + * cannot be cast to [Ljava.lang.Object; + * at org.apache.openjpa.jdbc.kernel.exps.Lit.appendTo(Lit.java:120) + * + * Notice the exception this time is in 'Lit'. Previous CCEx for the other tests have been in Param. + * With fix #1, the CCEx is avoided/resolved. However, we then got an incorrectly generated SQL as follows: + * + * SELECT t0.SUBJECTNUMMER, t0.CODE_SUBJECTTYPE FROM SUBJECT t0 WHERE (t0.SUBJECTNUMMER = ??) + * optimize for 1 row [params=(int) 1, (String) Type] + * + * Notice that 't0.CODE_SUBJECTTYPE' is missing, and there are two parameter markers. With fix #2.1 and + * #2.2, this issue is resolved. + * + * The other thing to note (which is different than the test 'findSubjectUsingCriteriaBuilderEqualsAndParameter' + * above) is that the Subject is treated as an OpenJPA 'Lit' (see changes in EqualExpression). The test + * 'findSubjectUsingCriteriaBuilderEqualsAndParameter' above treats the Subject as a Parameter. There is a bug in + * both cases, with an additional bug for the 'Lit' case. + */ + public void testFindSubjectUsingCriteriaBuilderEquals() { + + Subject s = createSubject(); + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<Subject> cq = builder.createQuery(Subject.class); + + Root<Subject> subjectRoot = cq.from(Subject.class); + cq.select(subjectRoot); + + Predicate subjectPredicate = builder.equal(subjectRoot, s); + + // Before the fix of JIRA OPENJPA-2631, the following was a way to fix/work around the issue, in + // other words, selecting the individual fields of the PK worked fine....I'll leave this here but + // commented out for history sake: + // Predicate subjectPredicate1 = builder.equal(subjectRoot.get(Subject_.key).get(SubjectKey_.subjectNummer), + // subject.getKey().getSubjectNummer()); + // Predicate subjectPredicate2 = builder.equal(subjectRoot.get(Subject_.key).get(SubjectKey_.subjectTypeCode), + // subject.getKey().getSubjectTypeCode()); + // Predicate subjectPredicate = builder.and(subjectPredicate1,subjectPredicate2); + + cq.where(subjectPredicate); + + TypedQuery<Subject> query = em.createQuery(cq); + + Subject s2 = query.getSingleResult(); + + verifySubject(s, s2); + } + + /* + * For comparison, this test does the same CriteriaBuilder code on Topic (an entity + * with a single PK) as was done in the previous test to make sure it works. + */ + public void testFindTopicUsingCriteriaBuilderEquals() { + + Topic t = new Topic(); + t.setId(5); + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<Topic> cq = builder.createQuery(Topic.class); + + Root<Topic> topicRoot = cq.from(Topic.class); + cq.select(topicRoot); + + Predicate topicPredicate = builder.equal(topicRoot, t); + cq.where(topicPredicate); + + TypedQuery<Topic> query = em.createQuery(cq); + + Topic topic = query.getSingleResult(); + + verifyResults(topic, createSubject()); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * Caused by: java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey + * cannot be cast to [Ljava.lang.Object; + * at org.apache.openjpa.jdbc.kernel.exps.Lit.appendTo(Lit.java:120) + * + * Notice the exception this time is in 'Lit'. Previous CCEx for the other tests have been in Param. + * With fix #1, the CCEx is avoided/resolved. However, we then got an incorrectly generated SQL as follows: + * + * SELECT t0.ID, t1.SUBJECTNUMMER, t1.CODE_SUBJECTTYPE FROM TOPIC t0 LEFT OUTER JOIN SUBJECT t1 ON + * t0.SUBJECT_SUBJECTNUMMER = + * t1.SUBJECTNUMMER AND t0.SUBJECT_CODE_SUBJECTTYPE = t1.CODE_SUBJECTTYPE WHERE (t0.SUBJECT_SUBJECTNUMMER = ??) + * optimize for 1 row [params=(int) 1, (String) Type] + * + * Notice that 't0.CODE_SUBJECTTYPE' is missing, and there are two parameter markers. With fix #2.1 and + * #2.2, this issue is resolved. + */ + public void testFindUsingCriteriaBuilderEquals() { + + Subject s = createSubject(); + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<Topic> cq = builder.createQuery(Topic.class); + + Root<Topic> topic = cq.from(Topic.class); + cq.select(topic).distinct(true); + + Predicate topicPredicate = builder.equal(topic.get("subject"), s); + cq.where(topicPredicate); + + TypedQuery<Topic> query = em.createQuery(cq); + Topic t = query.getSingleResult(); + + verifyResults(t, s); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * Caused by: java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey + * cannot be cast to [Ljava.lang.Object; + * at org.apache.openjpa.jdbc.kernel.exps.InExpression.orContains(InExpression.java:178) + * + * Notice this time the CCEx occurs in InExpression. With fix #1 the issue is resolved. + */ + public void testFindUsingJPQLInClauseOnSubject() { + Subject s = createSubject(); + SubjectKey key = new SubjectKey(999, "Bla"); + Subject s2 = new Subject(); + s2.setKey(key); + + List<Subject> subjectList = new ArrayList<Subject>(); + subjectList.add(s); + subjectList.add(s2); + + TypedQuery<Topic> query = em.createQuery( + "select distinct t from Topic t where t.subject in :subjectList", Topic.class); + query.setParameter("subjectList", subjectList); + Topic t = query.getSingleResult(); + + verifyResults(t, s); + } + + /* + * Prior to the fix #1 (see notes above), this fails on OJ with: + * + * Caused by: java.lang.ClassCastException: org.apache.openjpa.persistence.embed.compositepk.SubjectKey + * cannot be cast to [Ljava.lang.Object; + * at org.apache.openjpa.jdbc.kernel.exps.Lit.appendTo(Lit.java:120) + * + * Notice the exception this time is in 'Lit'. Previous CCEx for the other tests have been in Param. + * + * With fix #1, the CCEx is avoided/resolved. However, we then got an incorrectly generated SQL as follows: + * + * SELECT t0.ID, t1.SUBJECTNUMMER, t1.CODE_SUBJECTTYPE FROM TOPIC t0 LEFT OUTER JOIN SUBJECT t1 ON + * t0.SUBJECT_SUBJECTNUMMER = + * t1.SUBJECTNUMMER AND t0.SUBJECT_CODE_SUBJECTTYPE = t1.CODE_SUBJECTTYPE WHERE (t0.SUBJECT_SUBJECTNUMMER = ??) + * optimize for 1 row [params=(int) 1, (String) Type] + * + * Notice that 't0.CODE_SUBJECTTYPE' is missing, and there are two parameter markers. With fix #2.1 and + * #2.2, this issue is resolved. + */ + public void testFindUsingCriteriaBuilderInClauseOnSubject() { + + Subject s = createSubject(); + SubjectKey key = new SubjectKey(999, "Bla"); + Subject s2 = new Subject(); + s2.setKey(key); + + List<Subject> subjectList = new ArrayList<Subject>(); + subjectList.add(s); + subjectList.add(s2); + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<Topic> cq = builder.createQuery(Topic.class); + + Root<Topic> topic = cq.from(Topic.class); + cq.select(topic).distinct(true); + + Predicate subjectInSubjectList = topic.get(Topic_.subject).in(subjectList); + cq.where(subjectInSubjectList); + + TypedQuery<Topic> query = em.createQuery(cq); + Topic t = query.getSingleResult(); + + verifyResults(t, s); + } + + /* + * This test works fine with or without the fixes. This was added as a comparison to the case + * where an @EmbeddedId is used. In other words, this query selects a Subject which uses + * a @IdClass (still considered an embeddable in OpenJPA). + */ + public void testFindUsingJPQLEqualsOnSubjectWithIdClass() { + SubjectWithIdClass s = new SubjectWithIdClass(); + s.setSubjectNummer(1); + s.setSubjectTypeCode("Type"); + + TypedQuery<SubjectWithIdClass> query = + em.createQuery("select s from SubjectWithIdClass s where s = :subject", SubjectWithIdClass.class); + + query.setParameter("subject", s); + SubjectWithIdClass s2 = query.getSingleResult(); + + + Assert.assertNotNull(s2); + Assert.assertEquals(s.getSubjectNummer(), s2.getSubjectNummer()); + Assert.assertEquals(s.getSubjectTypeCode(), s2.getSubjectTypeCode()); + } + + /* + * For this test, the CCEx is actually never hit with or without the fixes. However, incorrect + * SQL was generated as follows: + * + * SELECT t0.SUBJECTNUMMER, t0.CODE_SUBJECTTYPE FROM SUBJECT2 t0 WHERE + * (t0.SUBJECTNUMMER = ??) optimize for 1 row [params=(int) 1, (String) Type]} + * + * Notice that 't0.CODE_SUBJECTTYPE' is missing, and there is an extra parameter marker. With + * fix #2.1 and #2.2 this issue is resolved. + */ + public void testFindUsingCriteriaBuilderOnSubjectWithIdClass() { + SubjectWithIdClass s = new SubjectWithIdClass(); + s.setSubjectNummer(1); + s.setSubjectTypeCode("Type"); + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery<SubjectWithIdClass> cq = builder.createQuery(SubjectWithIdClass.class); + + Root<SubjectWithIdClass> subjectRoot = cq.from(SubjectWithIdClass.class); + cq.select(subjectRoot); + + Predicate subjectPredicate = builder.equal(subjectRoot, s); + + cq.where(subjectPredicate); + + TypedQuery<SubjectWithIdClass> query = em.createQuery(cq); + + SubjectWithIdClass s2 = query.getSingleResult(); + + Assert.assertNotNull(s2); + Assert.assertEquals(s.getSubjectNummer(), s2.getSubjectNummer()); + Assert.assertEquals(s.getSubjectTypeCode(), s2.getSubjectTypeCode()); + } + + + private void createData(){ + Subject s = new Subject(); + SubjectKey sk = new SubjectKey(); + sk.setSubjectNummer(1); + sk.setSubjectType("Type2"); + s.setKey(sk); + em.persist(s); + + s = new Subject(); + sk = new SubjectKey(); + sk.setSubjectNummer(1); + sk.setSubjectType("Type"); + s.setKey(sk); + em.persist(s); + + Topic t = new Topic(); + t.setId(5); + t.setSubject(s); + em.persist(t); + + SubjectWithIdClass swic = new SubjectWithIdClass(); + swic.setSubjectNummer(1); + swic.setSubjectTypeCode("Type"); + em.persist(swic); + + swic = new SubjectWithIdClass(); + swic.setSubjectNummer(1); + swic.setSubjectTypeCode("Type2"); + em.persist(swic); + + em.flush(); + } + + private Subject createSubject() { + SubjectKey key = new SubjectKey(1, "Type"); + Subject result = new Subject(); + result.setKey(key); + + return result; + } + + public void verifyResults(Topic topic, Subject s) { + Assert.assertNotNull(topic); + Assert.assertEquals(new Integer(5), topic.getId()); + Subject s2 = topic.getSubject(); + verifySubject(s, s2); + } + + public void verifySubject(Subject expected, Subject actual) { + Assert.assertNotNull(expected); + Assert.assertEquals(expected.getKey().getSubjectNummer(), actual.getKey().getSubjectNummer()); + Assert.assertEquals(expected.getKey().getSubjectTypeCode(), actual.getKey().getSubjectTypeCode()); + } + + public void tearDown() { + if (tx != null && tx.isActive()) { + tx.rollback(); + tx = null; + } + + if (em != null && em.isOpen()) { + em.close(); + em = null; + } + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/TestCompositePrimaryKeys.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java Fri Jun 24 03:28:06 2016 @@ -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.embed.compositepk; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQuery; +import javax.persistence.Table; + +@Entity +@Table(name = "TOPIC") +@NamedQuery(name = "bySubject", query = "SELECT t FROM Topic t WHERE t.subject = :subject") +public class Topic { + @Id + @Column(name = "ID") + private Integer id; + + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.MERGE) +// @JoinColumns({ @JoinColumn(table = "TOPIC", name = "SUBJECTNUMMER", referencedColumnName = "SUBJECTNUMMER"), + // @JoinColumn(table = "TOPIC", name = "CODE_SUBJECTTYPE", referencedColumnName = "CODE_SUBJECTTYPE") }) + private Subject subject; + + public Topic() { + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Subject getSubject() { + return subject; + } + + public void setSubject(Subject subject) { + this.subject = subject; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((subject == null) ? 0 : subject.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; + Topic other = (Topic) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (subject == null) { + if (other.subject != null) + return false; + } else if (!subject.equals(other.subject)) + return false; + return true; + } +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java?rev=1750036&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java Fri Jun 24 03:28:06 2016 @@ -0,0 +1,30 @@ +/* + * 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.embed.compositepk; + +import javax.persistence.metamodel.SingularAttribute; + +@javax.persistence.metamodel.StaticMetamodel +(value=org.apache.openjpa.persistence.embed.compositepk.Topic.class) +@javax.annotation.Generated +(value="org.apache.openjpa.persistence.meta.AnnotationProcessor6",date="Fri Feb 05 14:31:20 MST 2016") +public class Topic_ { + public static volatile SingularAttribute<Topic,Integer> id; + public static volatile SingularAttribute<Topic,Subject> subject; +} Propchange: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/compositepk/Topic_.java ------------------------------------------------------------------------------ svn:eol-style = native