Bug 520387: EclipseLink metadata processing sets incorrect owning
descriptors
Signed-off-by: Will Dazey <dazeydev.3@gmail.com>
Reviewed-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/framework/junit/JUnitTestCase.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/framework/junit/JUnitTestCase.java
index 4f704b0..e6f1817 100644
--- a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/framework/junit/JUnitTestCase.java
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/framework/junit/JUnitTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -13,6 +13,8 @@
* - 329008: Support dynamic context creation without persistence.xml
* 01/23/2013-2.5 Guy Pelletier
* - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
******************************************************************************/
package org.eclipse.persistence.testing.framework.junit;
@@ -1001,6 +1003,16 @@ public static boolean isSelectForUpateNoWaitSupported(Platform platform) {
return false;
}
+ public static boolean supportsSequenceObjects(String puName) {
+ DatabasePlatform platform = getDatabaseSession(puName).getPlatform();
+ return platform.supportsSequenceObjects();
+ }
+
+ public boolean supportsSequenceObjects() {
+ DatabasePlatform platform = getDatabaseSession(getPersistenceUnitName()).getPlatform();
+ return platform.supportsSequenceObjects();
+ }
+
/**
* Return if stored procedures are supported for the database platform for the test database.
*/
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Author.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Author.java
new file mode 100644
index 0000000..37a2e9b
--- /dev/null
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Author.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
+ ******************************************************************************/
+package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="CMP3_AUTHOR")
+public class Author {
+
+ @EmbeddedId
+ private AuthorId id;
+ @Column(name="NAME")
+ private String name;
+
+ public Author() {
+ this.id = new AuthorId();
+ }
+
+ public Author(String name) {
+ this.id = new AuthorId();
+ this.name = name;
+ }
+
+ public AuthorId getId() {
+ return id;
+ }
+
+ public String toString() {
+ return "Author [id=" + this.id + ", name=" + this.name + "]";
+ }
+}
\ No newline at end of file
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/AuthorId.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/AuthorId.java
new file mode 100644
index 0000000..0011e86
--- /dev/null
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/AuthorId.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
+ ******************************************************************************/
+package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
+
+import java.io.Serializable;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+
+@Embeddable
+public class AuthorId implements Serializable {
+
+ private static final long serialVersionUID = -8247509662551594669L;
+
+ @Embedded
+ private NumberId numberId;
+
+ public AuthorId() {
+ this.numberId = new NumberId();
+ }
+
+ @Override
+ public int hashCode() {
+ return numberId.hashCode();
+ }
+
+ public NumberId getNumberId() {
+ return numberId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AuthorId other = (AuthorId) obj;
+ if (numberId == null) {
+ if (other.numberId != null)
+ return false;
+ } else if (!numberId.equals(other.numberId))
+ return false;
+ return true;
+ }
+
+ public String toString() {
+ return "AuthorId [numberId=" + this.numberId + "]";
+ }
+}
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Book.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Book.java
new file mode 100644
index 0000000..4c9f6da
--- /dev/null
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/Book.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
+ ******************************************************************************/
+package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="CMP3_BOOK")
+public class Book {
+
+ @EmbeddedId
+ private BookId id;
+ @Column(name="TITLE")
+ private String title;
+
+ public Book() {
+ this.id = new BookId();
+ this.title = "Default Title";
+ }
+
+ public Book(String title) {
+ this.id = new BookId();
+ this.title = title;
+ }
+
+ public BookId getId() {
+ return id;
+ }
+
+ public String toString() {
+ return "Book [id=" + this.id + ", title=" + this.title + "]";
+ }
+}
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/BookId.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/BookId.java
new file mode 100644
index 0000000..a52b995
--- /dev/null
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/BookId.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
+ ******************************************************************************/
+package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
+
+import java.io.Serializable;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+
+@Embeddable
+public class BookId implements Serializable {
+
+ private static final long serialVersionUID = -2930906625230816968L;
+
+ @Embedded
+ private NumberId numberId;
+
+ public BookId() {
+ this.numberId = new NumberId();
+ }
+
+ @Override
+ public int hashCode() {
+ return numberId.hashCode();
+ }
+
+ public NumberId getNumberId() {
+ return numberId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BookId other = (BookId) obj;
+ if (numberId == null) {
+ if (other.numberId != null)
+ return false;
+ } else if (!numberId.equals(other.numberId))
+ return false;
+ return true;
+ }
+
+ public String toString() {
+ return "BookId [numberId=" + this.numberId + "]";
+ }
+
+}
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/CompositePKTableCreator.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/CompositePKTableCreator.java
index 437f181..49d0ed4 100644
--- a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/CompositePKTableCreator.java
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/CompositePKTableCreator.java
@@ -23,6 +23,8 @@
* - 336122: ValidationException thrown for JoinColumns on OneToMany with composite primary key
* 01/06/2015-2.6 Dalia Abo Sheasha
* - 454917: Informix tables need to use INT fields when referencing SERIAL types.
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
******************************************************************************/
package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
@@ -1135,6 +1137,60 @@ public static TableDefinition buildADMINPOOLTable() {
return table;
}
+ public static TableDefinition buildAUTHORTable() {
+ TableDefinition table = new TableDefinition();
+ table.setName("CMP3_AUTHOR");
+
+ FieldDefinition ID_NUMBER_field = new FieldDefinition();
+ ID_NUMBER_field.setName("ID_NUMBER");
+ ID_NUMBER_field.setTypeName("NUMERIC");
+ ID_NUMBER_field.setSize(15);
+ ID_NUMBER_field.setShouldAllowNull(false);
+ ID_NUMBER_field.setIsPrimaryKey(true);
+ ID_NUMBER_field.setUnique(false);
+ ID_NUMBER_field.setIsIdentity(true);
+ table.addField(ID_NUMBER_field);
+
+ FieldDefinition F_NAME_field = new FieldDefinition();
+ F_NAME_field.setName("NAME");
+ F_NAME_field.setTypeName("VARCHAR");
+ F_NAME_field.setSize(40);
+ F_NAME_field.setShouldAllowNull(false);
+ F_NAME_field.setIsPrimaryKey(false);
+ F_NAME_field.setUnique(false);
+ F_NAME_field.setIsIdentity(true);
+ table.addField(F_NAME_field);
+
+ return table;
+ }
+
+ public static TableDefinition buildBOOKTable() {
+ TableDefinition table = new TableDefinition();
+ table.setName("CMP3_BOOK");
+
+ FieldDefinition ID_NUMBER_field = new FieldDefinition();
+ ID_NUMBER_field.setName("ID_NUMBER");
+ ID_NUMBER_field.setTypeName("NUMERIC");
+ ID_NUMBER_field.setSize(15);
+ ID_NUMBER_field.setShouldAllowNull(false);
+ ID_NUMBER_field.setIsPrimaryKey(true);
+ ID_NUMBER_field.setUnique(false);
+ ID_NUMBER_field.setIsIdentity(true);
+ table.addField(ID_NUMBER_field);
+
+ FieldDefinition F_NAME_field = new FieldDefinition();
+ F_NAME_field.setName("TITLE");
+ F_NAME_field.setTypeName("VARCHAR");
+ F_NAME_field.setSize(40);
+ F_NAME_field.setShouldAllowNull(false);
+ F_NAME_field.setIsPrimaryKey(false);
+ F_NAME_field.setUnique(false);
+ F_NAME_field.setIsIdentity(true);
+ table.addField(F_NAME_field);
+
+ return table;
+ }
+
/**
* Dropping old foreign keys from schema change.
*/
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/NumberId.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/NumberId.java
new file mode 100644
index 0000000..88ecfb6
--- /dev/null
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/NumberId.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
+ ******************************************************************************/
+package org.eclipse.persistence.testing.models.jpa.advanced.compositepk;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.GeneratedValue;
+import javax.persistence.SequenceGenerator;
+
+@Embeddable
+public class NumberId implements Serializable {
+
+ private static final long serialVersionUID = 4263409730381544959L;
+
+ @Column(name = "ID_NUMBER")
+ @SequenceGenerator(name = "ID_SEQ", sequenceName = "ID_SEQUENCE", allocationSize = 50, initialValue = 1000)
+ @GeneratedValue(generator = "ID_SEQ")
+ private Long value;
+
+ public NumberId() {
+ this(Long.valueOf(0L));
+ }
+
+ public NumberId(Long value) {
+ this.value = value;
+ }
+
+ public Long getValue() {
+ return value;
+ }
+
+ public final boolean equals(Object other) {
+ if (other == null) {
+ return false;
+ }
+ if (this == other) {
+ return true;
+ }
+ if (getClass() != other.getClass()) {
+ return false;
+ }
+ return Objects.equals(this.value, ((NumberId) other).value);
+ }
+
+ public final int hashCode() {
+ return Objects.hash(new Object[] { this.value });
+ }
+
+ public final String toString() {
+ return getClass().getSimpleName() + "[value=" + this.value + "]";
+ }
+}
diff --git a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/compositepk/AdvancedCompositePKJunitTest.java b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/compositepk/AdvancedCompositePKJunitTest.java
index ef03553..a1e9fc4 100644
--- a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/compositepk/AdvancedCompositePKJunitTest.java
+++ b/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/compositepk/AdvancedCompositePKJunitTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2016 Oracle and/or its affiliates, IBM Corporation. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates, IBM Corporation. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -19,6 +19,8 @@
* - 314941: multiple joinColumns without referenced column names defined, no error
* 01/25/2011-2.3 Guy Pelletier
* - 333913: @OrderBy and <order-by/> without arguments should order by primary
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
******************************************************************************/
package org.eclipse.persistence.testing.tests.jpa.advanced.compositepk;
@@ -35,12 +37,15 @@
import junit.framework.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
+import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Author;
+import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Book;
import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Competency;
import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.Cubicle;
import org.eclipse.persistence.testing.models.jpa.advanced.compositepk.JuniorScientist;
@@ -142,6 +147,7 @@ public static Test suite() {
suite.addTest(new AdvancedCompositePKJunitTest("testGetIdentifier"));
suite.addTest(new AdvancedCompositePKJunitTest("testFailedGetIdenitifier"));
suite.addTest(new AdvancedCompositePKJunitTest("testGetIdenitifierOnNonEntity"));
+ suite.addTest(new AdvancedCompositePKJunitTest("testNestedEmbeddableSequenceGeneration"));
}
return suite;
}
@@ -1024,4 +1030,24 @@ public void testGetIdenitifierOnNonEntity(){
}
fail("IllegalArgumentException not thrown for call to getIdentifier with a non-entity class.");
}
+
+ // bug 520387
+ public void testNestedEmbeddableSequenceGeneration(){
+ if(!supportsSequenceObjects()) {
+ return;
+ }
+
+ Book b = new Book("Book1");
+ Author a = new Author("Author1");
+
+ EntityManager em = createEntityManager();
+ beginTransaction(em);
+ b = (Book) em.merge(b);
+ a = (Author) em.merge(a);
+
+ assertTrue("The PK value for "+ b.getClass() +" (" + b.getId().getNumberId().getValue() + ") is not sequence generated", (b.getId().getNumberId().getValue() >= new Long(1000)));
+ assertTrue("The PK value for "+ a.getClass() +" (" + a.getId().getNumberId().getValue() + ") is not sequence generated", (a.getId().getNumberId().getValue() >= new Long(1000)));
+
+ rollbackTransaction(em);
+ }
}
diff --git a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/EmbeddableAccessor.java b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/EmbeddableAccessor.java
index e078694..2121c85 100644
--- a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/EmbeddableAccessor.java
+++ b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/EmbeddableAccessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -54,6 +54,8 @@
* - 251554: ExcludeDefaultMapping annotation needed
* 03/24/2011-2.3 Guy Pelletier
* - 337323: Multi-tenant with shared schema support (part 1)
+ * 09/11/2017-2.1 Will Dazey
+ * - 520387: multiple owning descriptors for an embeddable are not set
******************************************************************************/
package org.eclipse.persistence.internal.jpa.metadata.accessors.classes;
@@ -154,10 +156,12 @@ protected void addPotentialEmbeddableAccessor(MetadataClass potentialEmbeddableC
// another entity within the persistence unit.
EmbeddableAccessor embeddableAccessor = getProject().getEmbeddableAccessor(potentialEmbeddableClass, true);
- if (embeddableAccessor != null && ! embeddableAccessor.isPreProcessed()) {
+ if (embeddableAccessor != null) {
embeddableAccessor.addEmbeddingAccessor(embeddingAccessor);
embeddableAccessor.addOwningDescriptors(getOwningDescriptors());
- embeddableAccessor.preProcess();
+ if(!embeddableAccessor.isPreProcessed()) {
+ embeddableAccessor.preProcess();
+ }
}
}
}