You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by de...@apache.org on 2009/12/12 01:50:59 UTC
svn commit: r889871 - in /openjpa/branches/1.1.x:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-kernel/src/main/java/org/apache/openjpa/conf/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/
openjpa-persistence-jd...
Author: dezzio
Date: Sat Dec 12 00:50:58 2009
New Revision: 889871
URL: http://svn.apache.org/viewvc?rev=889871&view=rev
Log:
OpenJPA-1200: Applied patch supplied by Ravi Palacherla. Also changed EOL to native for modified files JDBCStoreManager and Compatibility.
Added:
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java (with props)
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java (with props)
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java (with props)
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java (with props)
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java (with props)
Modified:
openjpa/branches/1.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (contents, props changed)
openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java (contents, props changed)
Modified: openjpa/branches/1.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=889871&r1=889870&r2=889871&view=diff
==============================================================================
--- openjpa/branches/1.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/branches/1.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Sat Dec 12 00:50:58 2009
@@ -38,6 +38,7 @@
import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
import org.apache.openjpa.jdbc.sql.Joins;
@@ -898,13 +899,9 @@
OpenJPAStateManager sm, BitSet fields, JDBCFetchConfiguration fetch,
int eager, boolean ident, boolean outer) {
// add class conditions so that they're cloned for any batched selects
- boolean joinedSupers = false;
- if ((sm == null || sm.getPCState() == PCState.TRANSIENT)
- && (subs == Select.SUBS_JOINABLE || subs == Select.SUBS_NONE)) {
- loadSubclasses(mapping);
- Joins joins = (outer) ? sel.newOuterJoins() : null;
- joinedSupers = mapping.getDiscriminator().addClassConditions(sel,
- subs == Select.SUBS_JOINABLE, joins);
+ boolean joinedSupers = false;
+ if(needClassCondition(mapping, subs, sm)) {
+ joinedSupers = getJoinedSupers(sel, mapping, subs, outer);
}
// create all our eager selects so that those fields are reserved
@@ -935,6 +932,32 @@
return seld > 0;
}
+ private boolean getJoinedSupers(Select sel, ClassMapping mapping, int subs, boolean outer) {
+ loadSubclasses(mapping);
+ Joins joins = (outer) ? sel.newOuterJoins() : null;
+ return mapping.getDiscriminator().addClassConditions(sel, subs == Select.SUBS_JOINABLE, joins);
+ }
+
+ private boolean needClassCondition(ClassMapping mapping, int subs,
+ OpenJPAStateManager sm) {
+ boolean retVal = false;
+ if(sm == null || sm.getPCState() == PCState.TRANSIENT) {
+ if(subs == Select.SUBS_JOINABLE || subs == Select.SUBS_NONE) {
+ retVal = true;
+ }
+ else {
+ if (mapping.getDiscriminator() != null
+ && SuperclassDiscriminatorStrategy.class.isInstance(mapping.getDiscriminator().getStrategy())
+ && mapping.getMappingRepository().getConfiguration().getCompatibilityInstance()
+ .getSuperclassDiscriminatorStrategyByDefault()) {
+ retVal = true;
+ }
+ }
+ }
+ return retVal;
+ }
+
+
/**
* Mark the fields of this mapping as reserved so that eager fetches can't
* get into infinite recursive situations.
Modified: openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=889871&r1=889870&r2=889871&view=diff
==============================================================================
--- openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Sat Dec 12 00:50:58 2009
@@ -57,6 +57,7 @@
private boolean _storeMapCollectionInEntityAsBlob = false;
private boolean _flushBeforeDetach = true;
private boolean _autoOff = true;
+ private boolean _superclassDiscriminatorStrategyByDefault = true;
/**
* Whether to require exact identity value types when creating object
@@ -89,6 +90,22 @@
public void setAutoOff(boolean autoOff) {
_autoOff = autoOff;
}
+
+ /**
+ * Whether to add class criteria for super class discreminator strategy.
+ * Defaults to false.
+ */
+ public boolean getSuperclassDiscriminatorStrategyByDefault() {
+ return _superclassDiscriminatorStrategyByDefault;
+ }
+
+ /**
+ * Whether to add class criteria for super class discreminator strategy.
+ * Defaults to false.
+ */
+ public void setSuperclassDiscriminatorStrategyByDefault(boolean superclassDiscriminatorStrategyByDefault) {
+ _superclassDiscriminatorStrategyByDefault = superclassDiscriminatorStrategyByDefault;
+ }
/**
* Whether to interpret quoted numbers in query strings as numbers.
Propchange: openjpa/branches/1.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java?rev=889871&r1=889870&r2=889871&view=diff
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java (original)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java Sat Dec 12 00:50:58 2009
@@ -1,610 +1,611 @@
-/*
- * 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.enhance;
-
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ByteArrayInputStream;
-import java.util.List;
-import java.util.Collections;
-import java.lang.reflect.Field;
-
-import org.apache.openjpa.persistence.test.SingleEMFTestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.JPAFacadeHelper;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.event.AbstractLifecycleListener;
-import org.apache.openjpa.event.LifecycleEvent;
-
-public abstract class AbstractUnenhancedClassTest
- extends SingleEMFTestCase {
-
- // ##### To do:
- // - clearing in pnew property-access without redefinition
- // - figure out how to auto-test the redefinition code, either in Java 5
- // or in Java 6
- // - run CTS in the following combinations:
- // * Java 6
- // * Java 5 with javaagent
- // * Java 5 without javaagent
-
- public void setUp() {
- setUp(getUnenhancedClass(), getUnenhancedSubclass(), CLEAR_TABLES);
- // trigger class redefinition
- emf.createEntityManager().close();
- }
-
- protected abstract Class<? extends UnenhancedType> getUnenhancedClass();
-
- protected abstract UnenhancedType newUnenhancedInstance();
-
- protected abstract Class<? extends UnenhancedSubtype> getUnenhancedSubclass();
-
- protected abstract UnenhancedSubtype newUnenhancedSubclassInstance();
-
- private UnenhancedType newInstance(boolean sub) {
- return sub ? newUnenhancedSubclassInstance()
- : newUnenhancedInstance();
- }
-
- public void testMetaData() {
- ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
- getUnenhancedClass());
- assertEquals(ClassRedefiner.canRedefineClasses(),
- meta.isIntercepting());
- }
-
- public void testImplHelperCalls() {
- assertTrue(ImplHelper.isManagedType(null, getUnenhancedClass()));
-
- UnenhancedType un = newUnenhancedInstance();
- assertFalse(un instanceof PersistenceCapable);
- PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
- emf.getConfiguration());
- assertNotNull(pc);
- assertTrue(ImplHelper.isManageable(un));
- }
-
- public void testBasicPersistenceCapableBehavior() {
- UnenhancedType un = newUnenhancedInstance();
- un.setStringField("bar");
- PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
- emf.getConfiguration());
- assertFalse(pc.pcIsDeleted());
- assertFalse(pc.pcIsDirty());
- assertFalse(pc.pcIsNew());
- assertFalse(pc.pcIsPersistent());
- assertFalse(pc.pcIsTransactional());
- }
-
- public void testPCRegistry() {
- assertTrue(PCRegistry.isRegistered(getUnenhancedClass()));
- PersistenceCapable pc = PCRegistry.newInstance(
- getUnenhancedClass(), null, false);
- assertNotNull(pc);
- assertEquals(pc.getClass(), PCRegistry.getPCType(getUnenhancedClass()));
- }
-
- public void testClearingOnSubtypeInstance() {
- // the boolean at the end of newInstance will cause clear to be invoked
- UnenhancedType un = (UnenhancedType)
- PCRegistry.newInstance(getUnenhancedClass(), null, true);
- assertEquals(null, un.getStringField());
- }
-
- public void testGetObjectIdOnOpenJPAType() {
- getObjectIdHelper(true, false);
- }
-
- public void testGetObjectIdOnOpenJPATypeSubclass() {
- getObjectIdHelper(false, false);
- }
-
- public void testGetObjectIdOnUserDefined() {
- getObjectIdHelper(true, true);
- }
-
- public void testGetObjectIdOnUserDefinedSubclass() {
- getObjectIdHelper(false, true);
- }
-
- private void getObjectIdHelper(boolean sub, boolean userDefined) {
- OpenJPAEntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- UnenhancedType un = newInstance(sub);
- em.persist(un);
- em.getTransaction().commit();
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- un = em.find(getUnenhancedClass(), un.getId());
- }
-
- assertNotNull(em.getObjectId(un));
- }
-
- public void testOperationsOnUserDefined() {
- opsHelper(false, true);
- }
-
- public void testSubclassOperationsOnUserDefined() {
- opsHelper(true, true);
- }
-
- public void testOperationsOnOpenJPADefined() {
- opsHelper(false, false);
- }
-
- public void testSubclassOperationsOnOpenJPADefined() {
- opsHelper(true, false);
- }
-
- private void opsHelper(boolean sub, boolean userDefined) {
- OpenJPAEntityManager em = null;
- try {
- UnenhancedType un = newInstance(sub);
- em = emf.createEntityManager();
-
- em.getTransaction().begin();
- em.persist(un);
- un.setStringField("bar");
- assertEquals("bar", un.getStringField());
- assertPersistenceContext(em, un, true, true, sub);
- em.flush();
- assertPersistenceContext(em, un, true, true, sub);
- assertTrue(un.getId() != 0);
- UnenhancedType un2 = em.find(getUnenhancedClass(), un.getId());
- assertSame(un, un2);
- em.getTransaction().commit();
- assertPersistenceContext(em, un, false, false, sub);
- un2 = em.find(getUnenhancedClass(), un.getId());
- assertSame(un, un2);
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- }
-
- un = em.find(getUnenhancedClass(), un.getId());
- assertNotNull(un);
- if (!userDefined)
- assertTrue(un instanceof PersistenceCapable);
- assertEquals("bar", un.getStringField());
- em.getTransaction().begin();
- un.setStringField("baz");
- assertPersistenceContext(em, un, true, true, sub);
- assertEquals("baz", un.getStringField());
-
- if (sub)
- ((UnenhancedSubtype) un).setIntField(17);
-
- assertTrue(em.isDirty(un));
-
- em.getTransaction().commit();
-
- // make sure that the values are still up-to-date after
- // the commit happens
- assertEquals("baz", un.getStringField());
-
- em.close();
-
- em = emf.createEntityManager();
- un = em.find(getUnenhancedClass(), un.getId());
- assertNotNull(un);
- assertTrue(un instanceof PersistenceCapable);
- assertEquals("baz", un.getStringField());
- if (sub)
- assertEquals(17, ((UnenhancedSubtype) un).getIntField());
- em.close();
- } finally {
- if (em != null && em.getTransaction().isActive())
- em.getTransaction().rollback();
- if (em != null && em.isOpen())
- em.close();
- }
- }
-
- private void assertPersistenceContext(OpenJPAEntityManager em,
- UnenhancedType un, boolean transactional, boolean dirty, boolean sub) {
- assertEquals(transactional, em.getTransactionalObjects().contains(un));
- assertEquals(dirty, em.getDirtyObjects().contains(un));
- if (dirty) {
- Class cls = sub ? getUnenhancedSubclass() : getUnenhancedClass();
- assertTrue(em.getUpdatedClasses().contains(cls)
- || em.getPersistedClasses().contains(cls));
- }
- }
-
- public void testRelations() {
- OpenJPAEntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- UnenhancedSubtype un = newUnenhancedSubclassInstance();
- em.persist(un);
- un.setStringField("aoeu");
- UnenhancedSubtype related = newUnenhancedSubclassInstance();
- un.setRelated(related);
- related.setStringField("snth");
- em.getTransaction().commit();
- em.close();
-
- em = emf.createEntityManager();
- un = (UnenhancedSubtype) em.find(getUnenhancedClass(), un.getId());
- assertEquals("aoeu", un.getStringField());
- assertNotNull(un.getRelated());
- assertEquals("snth", un.getRelated().getStringField());
- em.close();
- }
-
- public void testEnhancer() throws IOException {
- List<Class> subs = ManagedClassSubclasser.prepareUnenhancedClasses(
- emf.getConfiguration(),
- Collections.singleton(getUnenhancedClass()), null);
- Class sub = subs.get(0);
- assertNotNull(sub);
- assertEquals("org.apache.openjpa.enhance."
- + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
- sub.getName());
- assertTrue(PersistenceCapable.class.isAssignableFrom(sub));
- assertTrue(getUnenhancedClass().isAssignableFrom(sub));
- }
-
- public void testPCSubclassName() {
- assertEquals("org.apache.openjpa.enhance."
- + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
- PCEnhancer.toPCSubclassName(getUnenhancedClass()));
- }
-
- public void testEvictionInUserCreatedInstance()
- throws NoSuchFieldException, IllegalAccessException {
- evictionHelper(true);
- }
-
- public void testEvictionInOpenJPACreatedInstance()
- throws NoSuchFieldException, IllegalAccessException {
- evictionHelper(false);
- }
-
- private void evictionHelper(boolean userDefined)
- throws NoSuchFieldException, IllegalAccessException {
- OpenJPAEntityManager em = emf.createEntityManager();
- UnenhancedType un = newUnenhancedInstance();
- em.getTransaction().begin();
- em.persist(un);
- em.getTransaction().commit();
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- un = em.find(getUnenhancedClass(), un.getId());
- assertTrue(getUnenhancedClass() != un.getClass());
- }
-
- em.evict(un);
- OpenJPAStateManager sm = (OpenJPAStateManager)
- ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
-
- // we only expect lazy loading to work when we can redefine classes
- // or when accessing a property-access record that OpenJPA created.
- if (ClassRedefiner.canRedefineClasses()
- || (!userDefined && sm.getMetaData().getAccessType()
- != ClassMetaData.ACCESS_FIELD)) {
-
- assertFalse(sm.getLoaded()
- .get(sm.getMetaData().getField("stringField").getIndex()));
-
- // make sure that the value was cleared...
- Field field = getUnenhancedClass().getDeclaredField(
- isFieldAccessTest() ? "stringField" : "sf");
- field.setAccessible(true);
- assertEquals(null, field.get(un));
-
- // ... and that it gets reloaded properly
- assertEquals("foo", un.getStringField());
- assertTrue(sm.getLoaded()
- .get(sm.getMetaData().getField("stringField").getIndex()));
- } else {
- // unredefined properties with user-defined instance, or any
- // unredefined field access
- assertTrue(sm.getLoaded()
- .get(sm.getMetaData().getField("stringField").getIndex()));
-
- // make sure that the value was not cleared
- Field field = getUnenhancedClass().getDeclaredField(
- isFieldAccessTest() ? "stringField" : "sf");
- field.setAccessible(true);
- assertEquals("foo", field.get(un));
- }
-
- em.close();
- }
-
- protected abstract boolean isFieldAccessTest();
-
- public void testLazyLoading()
- throws NoSuchFieldException, IllegalAccessException {
- OpenJPAEntityManager em = emf.createEntityManager();
- UnenhancedType un = newUnenhancedInstance();
- em.getTransaction().begin();
- em.persist(un);
- em.getTransaction().commit();
- em.close();
-
- em = emf.createEntityManager();
- un = em.find(getUnenhancedClass(), un.getId());
- assertTrue(getUnenhancedClass() != un.getClass());
- OpenJPAStateManager sm = (OpenJPAStateManager)
- ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
-
- // we only expect lazy loading to work when we can redefine classes
- // or when accessing a property-access record that OpenJPA created.
- if (ClassRedefiner.canRedefineClasses()
- || (sm.getMetaData().getAccessType() != ClassMetaData.ACCESS_FIELD))
- {
- assertFalse(sm.getLoaded()
- .get(sm.getMetaData().getField("lazyField").getIndex()));
-
- // make sure that the value was cleared
- Field field = getUnenhancedClass().getDeclaredField("lazyField");
- field.setAccessible(true);
- assertEquals(null, field.get(un));
- } else {
- // unredefined field access
- assertTrue(sm.getLoaded()
- .get(sm.getMetaData().getField("lazyField").getIndex()));
-
- // make sure that the value was loaded already
- Field field = getUnenhancedClass().getDeclaredField("lazyField");
- field.setAccessible(true);
- assertEquals("lazy", field.get(un));
- }
-
- // make sure that the value is available, one way or another
- assertEquals("lazy", un.getLazyField());
- assertTrue(sm.getLoaded()
- .get(sm.getMetaData().getField("lazyField").getIndex()));
-
- em.close();
- }
-
- public void testSerializationOfUserDefinedInstance()
- throws IOException, ClassNotFoundException {
- serializationHelper(true, false);
- }
-
- public void testSerializationOfUserDefinedSubclassInstance()
- throws IOException, ClassNotFoundException {
- serializationHelper(true, true);
- }
-
- public void testSerializationOfOpenJPADefinedInstance()
- throws IOException, ClassNotFoundException {
- serializationHelper(false, false);
- }
-
- public void testSerializationOfOpenJPADefinedSubclassInstance()
- throws IOException, ClassNotFoundException {
- serializationHelper(false, true);
- }
-
- private void serializationHelper(boolean userDefined, boolean sub)
- throws IOException, ClassNotFoundException {
- OpenJPAEntityManager em = emf.createEntityManager();
- UnenhancedType un = newInstance(sub);
- em.getTransaction().begin();
- em.persist(un);
-
- if (sub) {
- UnenhancedType related = newInstance(false);
- related.setStringField("related");
- ((UnenhancedSubtype) un).setRelated(related);
- }
-
- em.getTransaction().commit();
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- }
-
- un = em.find(getUnenhancedClass(), un.getId());
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(out);
- oout.writeObject(un);
- oout.flush();
- byte[] bytes = out.toByteArray();
-
- ObjectInputStream oin = new ObjectInputStream(
- new ByteArrayInputStream(bytes));
- UnenhancedType deserialized = (UnenhancedType) oin.readObject();
-
- copiedInstanceHelper(sub, em, un, deserialized, false);
- em.close();
- }
-
- public void testCloningOfUserDefinedInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- cloneHelper(true, false);
- }
-
- public void testCloningOfUserDefinedSubclassInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- cloneHelper(true, true);
- }
-
- public void testCloningOfOpenJPADefinedInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- cloneHelper(false, false);
- }
-
- public void testCloningOfOpenJPADefinedSubclassInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- cloneHelper(false, true);
- }
-
- private void cloneHelper(boolean userDefined, boolean sub)
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- OpenJPAEntityManager em = emf.createEntityManager();
- UnenhancedType un = newInstance(sub);
- em.getTransaction().begin();
- em.persist(un);
-
- if (sub) {
- UnenhancedType related = newInstance(false);
- related.setStringField("related");
- ((UnenhancedSubtype) un).setRelated(related);
- }
-
- em.getTransaction().commit();
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- }
-
- un = em.find(getUnenhancedClass(), un.getId());
- UnenhancedType cloned = (UnenhancedType) un.clone();
-
- copiedInstanceHelper(sub, em, un, cloned, true);
- em.close();
- }
-
- private void copiedInstanceHelper(boolean sub, OpenJPAEntityManager em,
- UnenhancedType un, UnenhancedType copy, boolean viaClone) {
- assertNotSame(un, copy);
- if (!viaClone)
- assertEquals(sub ? getUnenhancedSubclass() : getUnenhancedClass(),
- copy.getClass());
- assertEquals(un.getId(), copy.getId());
- assertEquals(un.getStringField(), copy.getStringField());
- if (sub) {
- assertEquals(
- ((UnenhancedSubtype) un).getIntField(),
- ((UnenhancedSubtype) copy).getIntField());
- assertNotSame(
- ((UnenhancedSubtype) un).getRelated(),
- ((UnenhancedSubtype) copy).getRelated());
- assertEquals(
- ((UnenhancedSubtype) un).getRelated().getId(),
- ((UnenhancedSubtype) copy).getRelated().getId());
- }
-
- assertFalse(em.isDetached(un));
- assertTrue(em.isDetached(copy));
-
- /*
- ##### need to make detachment algorithm in ReflectingPC smarter
- // ensure that remove() cannot be invoked on a detached instance
- try {
- em.getTransaction().begin();
- em.remove(copy);
- fail("remove() cannot be invoked on detached instance");
- } catch (IllegalArgumentException e) {
- em.getTransaction().rollback();
- }
- */
-
- copy.setStringField("offline update");
-
- em.getTransaction().begin();
- assertSame(un, em.merge(copy));
- assertTrue(em.isDirty(un));
- assertEquals("offline update", un.getStringField());
- em.getTransaction().commit();
- }
-
- public void testListenersOnUserDefinedInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- listenerHelper(true, false);
- }
-
- public void testListenersOnUserDefinedSubclassInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- listenerHelper(true, true);
- }
-
- public void testListenersOnOpenJPADefinedInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- listenerHelper(false, false);
- }
-
- public void testListenersOnOpenJPADefinedSubclassInstance()
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- listenerHelper(false, true);
- }
-
- private void listenerHelper(boolean userDefined, boolean sub)
- throws IOException, ClassNotFoundException, CloneNotSupportedException {
- ListenerImpl listener = new ListenerImpl();
- emf.addLifecycleListener(listener, (Class[]) null);
- OpenJPAEntityManager em = emf.createEntityManager();
- UnenhancedType un = newInstance(sub);
- em.getTransaction().begin();
- em.persist(un);
- em.getTransaction().commit();
-
- if (!userDefined) {
- em.close();
- em = emf.createEntityManager();
- }
-
- listener.invoked = false;
-
- un = em.find(getUnenhancedClass(), un.getId());
- em.getTransaction().begin();
- un.setStringField("updated");
- em.getTransaction().commit();
- assertTrue(listener.invoked);
- em.close();
-
- assertEquals("updated", listener.stringField);
- }
-
- public void testGetMetaDataOfSubtype() {
- ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
- getUnenhancedClass());
- List<Class> subs = ManagedClassSubclasser.prepareUnenhancedClasses(
- emf.getConfiguration(),
- Collections.singleton(getUnenhancedClass()), null);
- assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
-
- meta = JPAFacadeHelper.getMetaData(emf, getUnenhancedSubclass());
- subs = ManagedClassSubclasser.prepareUnenhancedClasses(
- emf.getConfiguration(),
- Collections.singleton(getUnenhancedSubclass()), null);
- assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
- }
-
- private class ListenerImpl
- extends AbstractLifecycleListener {
-
- String stringField;
- boolean invoked;
-
- @Override
- public void afterStore(LifecycleEvent event) {
- invoked = true;
- stringField = ((UnenhancedType) event.getSource()).getStringField();
- }
- }
+/*
+ * 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.enhance;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Collections;
+import java.lang.reflect.Field;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.jdbc.kernel.A;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.event.AbstractLifecycleListener;
+import org.apache.openjpa.event.LifecycleEvent;
+
+public abstract class AbstractUnenhancedClassTest
+ extends SingleEMFTestCase {
+
+ // ##### To do:
+ // - clearing in pnew property-access without redefinition
+ // - figure out how to auto-test the redefinition code, either in Java 5
+ // or in Java 6
+ // - run CTS in the following combinations:
+ // * Java 6
+ // * Java 5 with javaagent
+ // * Java 5 without javaagent
+
+ public void setUp() {
+ setUp(getUnenhancedClass(), getUnenhancedSubclass(), CLEAR_TABLES, "openjpa.Compatibility", "superclassDiscriminatorStrategyByDefault=false");
+ // trigger class redefinition
+ emf.createEntityManager().close();
+ }
+
+ protected abstract Class<? extends UnenhancedType> getUnenhancedClass();
+
+ protected abstract UnenhancedType newUnenhancedInstance();
+
+ protected abstract Class<? extends UnenhancedSubtype> getUnenhancedSubclass();
+
+ protected abstract UnenhancedSubtype newUnenhancedSubclassInstance();
+
+ private UnenhancedType newInstance(boolean sub) {
+ return sub ? newUnenhancedSubclassInstance()
+ : newUnenhancedInstance();
+ }
+
+ public void testMetaData() {
+ ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
+ getUnenhancedClass());
+ assertEquals(ClassRedefiner.canRedefineClasses(),
+ meta.isIntercepting());
+ }
+
+ public void testImplHelperCalls() {
+ assertTrue(ImplHelper.isManagedType(null, getUnenhancedClass()));
+
+ UnenhancedType un = newUnenhancedInstance();
+ assertFalse(un instanceof PersistenceCapable);
+ PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
+ emf.getConfiguration());
+ assertNotNull(pc);
+ assertTrue(ImplHelper.isManageable(un));
+ }
+
+ public void testBasicPersistenceCapableBehavior() {
+ UnenhancedType un = newUnenhancedInstance();
+ un.setStringField("bar");
+ PersistenceCapable pc = ImplHelper.toPersistenceCapable(un,
+ emf.getConfiguration());
+ assertFalse(pc.pcIsDeleted());
+ assertFalse(pc.pcIsDirty());
+ assertFalse(pc.pcIsNew());
+ assertFalse(pc.pcIsPersistent());
+ assertFalse(pc.pcIsTransactional());
+ }
+
+ public void testPCRegistry() {
+ assertTrue(PCRegistry.isRegistered(getUnenhancedClass()));
+ PersistenceCapable pc = PCRegistry.newInstance(
+ getUnenhancedClass(), null, false);
+ assertNotNull(pc);
+ assertEquals(pc.getClass(), PCRegistry.getPCType(getUnenhancedClass()));
+ }
+
+ public void testClearingOnSubtypeInstance() {
+ // the boolean at the end of newInstance will cause clear to be invoked
+ UnenhancedType un = (UnenhancedType)
+ PCRegistry.newInstance(getUnenhancedClass(), null, true);
+ assertEquals(null, un.getStringField());
+ }
+
+ public void testGetObjectIdOnOpenJPAType() {
+ getObjectIdHelper(true, false);
+ }
+
+ public void testGetObjectIdOnOpenJPATypeSubclass() {
+ getObjectIdHelper(false, false);
+ }
+
+ public void testGetObjectIdOnUserDefined() {
+ getObjectIdHelper(true, true);
+ }
+
+ public void testGetObjectIdOnUserDefinedSubclass() {
+ getObjectIdHelper(false, true);
+ }
+
+ private void getObjectIdHelper(boolean sub, boolean userDefined) {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ UnenhancedType un = newInstance(sub);
+ em.persist(un);
+ em.getTransaction().commit();
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ un = em.find(getUnenhancedClass(), un.getId());
+ }
+
+ assertNotNull(em.getObjectId(un));
+ }
+
+ public void testOperationsOnUserDefined() {
+ opsHelper(false, true);
+ }
+
+ public void testSubclassOperationsOnUserDefined() {
+ opsHelper(true, true);
+ }
+
+ public void testOperationsOnOpenJPADefined() {
+ opsHelper(false, false);
+ }
+
+ public void testSubclassOperationsOnOpenJPADefined() {
+ opsHelper(true, false);
+ }
+
+ private void opsHelper(boolean sub, boolean userDefined) {
+ OpenJPAEntityManager em = null;
+ try {
+ UnenhancedType un = newInstance(sub);
+ em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.persist(un);
+ un.setStringField("bar");
+ assertEquals("bar", un.getStringField());
+ assertPersistenceContext(em, un, true, true, sub);
+ em.flush();
+ assertPersistenceContext(em, un, true, true, sub);
+ assertTrue(un.getId() != 0);
+ UnenhancedType un2 = em.find(getUnenhancedClass(), un.getId());
+ assertSame(un, un2);
+ em.getTransaction().commit();
+ assertPersistenceContext(em, un, false, false, sub);
+ un2 = em.find(getUnenhancedClass(), un.getId());
+ assertSame(un, un2);
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ }
+
+ un = em.find(getUnenhancedClass(), un.getId());
+ assertNotNull(un);
+ if (!userDefined)
+ assertTrue(un instanceof PersistenceCapable);
+ assertEquals("bar", un.getStringField());
+ em.getTransaction().begin();
+ un.setStringField("baz");
+ assertPersistenceContext(em, un, true, true, sub);
+ assertEquals("baz", un.getStringField());
+
+ if (sub)
+ ((UnenhancedSubtype) un).setIntField(17);
+
+ assertTrue(em.isDirty(un));
+
+ em.getTransaction().commit();
+
+ // make sure that the values are still up-to-date after
+ // the commit happens
+ assertEquals("baz", un.getStringField());
+
+ em.close();
+
+ em = emf.createEntityManager();
+ un = em.find(getUnenhancedClass(), un.getId());
+ assertNotNull(un);
+ assertTrue(un instanceof PersistenceCapable);
+ assertEquals("baz", un.getStringField());
+ if (sub)
+ assertEquals(17, ((UnenhancedSubtype) un).getIntField());
+ em.close();
+ } finally {
+ if (em != null && em.getTransaction().isActive())
+ em.getTransaction().rollback();
+ if (em != null && em.isOpen())
+ em.close();
+ }
+ }
+
+ private void assertPersistenceContext(OpenJPAEntityManager em,
+ UnenhancedType un, boolean transactional, boolean dirty, boolean sub) {
+ assertEquals(transactional, em.getTransactionalObjects().contains(un));
+ assertEquals(dirty, em.getDirtyObjects().contains(un));
+ if (dirty) {
+ Class cls = sub ? getUnenhancedSubclass() : getUnenhancedClass();
+ assertTrue(em.getUpdatedClasses().contains(cls)
+ || em.getPersistedClasses().contains(cls));
+ }
+ }
+
+ public void testRelations() {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ UnenhancedSubtype un = newUnenhancedSubclassInstance();
+ em.persist(un);
+ un.setStringField("aoeu");
+ UnenhancedSubtype related = newUnenhancedSubclassInstance();
+ un.setRelated(related);
+ related.setStringField("snth");
+ em.getTransaction().commit();
+ em.close();
+
+ em = emf.createEntityManager();
+ un = (UnenhancedSubtype) em.find(getUnenhancedClass(), un.getId());
+ assertEquals("aoeu", un.getStringField());
+ assertNotNull(un.getRelated());
+ assertEquals("snth", un.getRelated().getStringField());
+ em.close();
+ }
+
+ public void testEnhancer() throws IOException {
+ List<Class> subs = ManagedClassSubclasser.prepareUnenhancedClasses(
+ emf.getConfiguration(),
+ Collections.singleton(getUnenhancedClass()), null);
+ Class sub = subs.get(0);
+ assertNotNull(sub);
+ assertEquals("org.apache.openjpa.enhance."
+ + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
+ sub.getName());
+ assertTrue(PersistenceCapable.class.isAssignableFrom(sub));
+ assertTrue(getUnenhancedClass().isAssignableFrom(sub));
+ }
+
+ public void testPCSubclassName() {
+ assertEquals("org.apache.openjpa.enhance."
+ + getUnenhancedClass().getName().replace('.', '$') + "$pcsubclass",
+ PCEnhancer.toPCSubclassName(getUnenhancedClass()));
+ }
+
+ public void testEvictionInUserCreatedInstance()
+ throws NoSuchFieldException, IllegalAccessException {
+ evictionHelper(true);
+ }
+
+ public void testEvictionInOpenJPACreatedInstance()
+ throws NoSuchFieldException, IllegalAccessException {
+ evictionHelper(false);
+ }
+
+ private void evictionHelper(boolean userDefined)
+ throws NoSuchFieldException, IllegalAccessException {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ UnenhancedType un = newUnenhancedInstance();
+ em.getTransaction().begin();
+ em.persist(un);
+ em.getTransaction().commit();
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ un = em.find(getUnenhancedClass(), un.getId());
+ assertTrue(getUnenhancedClass() != un.getClass());
+ }
+
+ em.evict(un);
+ OpenJPAStateManager sm = (OpenJPAStateManager)
+ ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
+
+ // we only expect lazy loading to work when we can redefine classes
+ // or when accessing a property-access record that OpenJPA created.
+ if (ClassRedefiner.canRedefineClasses()
+ || (!userDefined && sm.getMetaData().getAccessType()
+ != ClassMetaData.ACCESS_FIELD)) {
+
+ assertFalse(sm.getLoaded()
+ .get(sm.getMetaData().getField("stringField").getIndex()));
+
+ // make sure that the value was cleared...
+ Field field = getUnenhancedClass().getDeclaredField(
+ isFieldAccessTest() ? "stringField" : "sf");
+ field.setAccessible(true);
+ assertEquals(null, field.get(un));
+
+ // ... and that it gets reloaded properly
+ assertEquals("foo", un.getStringField());
+ assertTrue(sm.getLoaded()
+ .get(sm.getMetaData().getField("stringField").getIndex()));
+ } else {
+ // unredefined properties with user-defined instance, or any
+ // unredefined field access
+ assertTrue(sm.getLoaded()
+ .get(sm.getMetaData().getField("stringField").getIndex()));
+
+ // make sure that the value was not cleared
+ Field field = getUnenhancedClass().getDeclaredField(
+ isFieldAccessTest() ? "stringField" : "sf");
+ field.setAccessible(true);
+ assertEquals("foo", field.get(un));
+ }
+
+ em.close();
+ }
+
+ protected abstract boolean isFieldAccessTest();
+
+ public void testLazyLoading()
+ throws NoSuchFieldException, IllegalAccessException {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ UnenhancedType un = newUnenhancedInstance();
+ em.getTransaction().begin();
+ em.persist(un);
+ em.getTransaction().commit();
+ em.close();
+
+ em = emf.createEntityManager();
+ un = em.find(getUnenhancedClass(), un.getId());
+ assertTrue(getUnenhancedClass() != un.getClass());
+ OpenJPAStateManager sm = (OpenJPAStateManager)
+ ImplHelper.toPersistenceCapable(un, null).pcGetStateManager();
+
+ // we only expect lazy loading to work when we can redefine classes
+ // or when accessing a property-access record that OpenJPA created.
+ if (ClassRedefiner.canRedefineClasses()
+ || (sm.getMetaData().getAccessType() != ClassMetaData.ACCESS_FIELD))
+ {
+ assertFalse(sm.getLoaded()
+ .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+ // make sure that the value was cleared
+ Field field = getUnenhancedClass().getDeclaredField("lazyField");
+ field.setAccessible(true);
+ assertEquals(null, field.get(un));
+ } else {
+ // unredefined field access
+ assertTrue(sm.getLoaded()
+ .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+ // make sure that the value was loaded already
+ Field field = getUnenhancedClass().getDeclaredField("lazyField");
+ field.setAccessible(true);
+ assertEquals("lazy", field.get(un));
+ }
+
+ // make sure that the value is available, one way or another
+ assertEquals("lazy", un.getLazyField());
+ assertTrue(sm.getLoaded()
+ .get(sm.getMetaData().getField("lazyField").getIndex()));
+
+ em.close();
+ }
+
+ public void testSerializationOfUserDefinedInstance()
+ throws IOException, ClassNotFoundException {
+ serializationHelper(true, false);
+ }
+
+ public void testSerializationOfUserDefinedSubclassInstance()
+ throws IOException, ClassNotFoundException {
+ serializationHelper(true, true);
+ }
+
+ public void testSerializationOfOpenJPADefinedInstance()
+ throws IOException, ClassNotFoundException {
+ serializationHelper(false, false);
+ }
+
+ public void testSerializationOfOpenJPADefinedSubclassInstance()
+ throws IOException, ClassNotFoundException {
+ serializationHelper(false, true);
+ }
+
+ private void serializationHelper(boolean userDefined, boolean sub)
+ throws IOException, ClassNotFoundException {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ UnenhancedType un = newInstance(sub);
+ em.getTransaction().begin();
+ em.persist(un);
+
+ if (sub) {
+ UnenhancedType related = newInstance(false);
+ related.setStringField("related");
+ ((UnenhancedSubtype) un).setRelated(related);
+ }
+
+ em.getTransaction().commit();
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ }
+
+ un = em.find(getUnenhancedClass(), un.getId());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream oout = new ObjectOutputStream(out);
+ oout.writeObject(un);
+ oout.flush();
+ byte[] bytes = out.toByteArray();
+
+ ObjectInputStream oin = new ObjectInputStream(
+ new ByteArrayInputStream(bytes));
+ UnenhancedType deserialized = (UnenhancedType) oin.readObject();
+
+ copiedInstanceHelper(sub, em, un, deserialized, false);
+ em.close();
+ }
+
+ public void testCloningOfUserDefinedInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ cloneHelper(true, false);
+ }
+
+ public void testCloningOfUserDefinedSubclassInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ cloneHelper(true, true);
+ }
+
+ public void testCloningOfOpenJPADefinedInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ cloneHelper(false, false);
+ }
+
+ public void testCloningOfOpenJPADefinedSubclassInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ cloneHelper(false, true);
+ }
+
+ private void cloneHelper(boolean userDefined, boolean sub)
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ OpenJPAEntityManager em = emf.createEntityManager();
+ UnenhancedType un = newInstance(sub);
+ em.getTransaction().begin();
+ em.persist(un);
+
+ if (sub) {
+ UnenhancedType related = newInstance(false);
+ related.setStringField("related");
+ ((UnenhancedSubtype) un).setRelated(related);
+ }
+
+ em.getTransaction().commit();
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ }
+
+ un = em.find(getUnenhancedClass(), un.getId());
+ UnenhancedType cloned = (UnenhancedType) un.clone();
+
+ copiedInstanceHelper(sub, em, un, cloned, true);
+ em.close();
+ }
+
+ private void copiedInstanceHelper(boolean sub, OpenJPAEntityManager em,
+ UnenhancedType un, UnenhancedType copy, boolean viaClone) {
+ assertNotSame(un, copy);
+ if (!viaClone)
+ assertEquals(sub ? getUnenhancedSubclass() : getUnenhancedClass(),
+ copy.getClass());
+ assertEquals(un.getId(), copy.getId());
+ assertEquals(un.getStringField(), copy.getStringField());
+ if (sub) {
+ assertEquals(
+ ((UnenhancedSubtype) un).getIntField(),
+ ((UnenhancedSubtype) copy).getIntField());
+ assertNotSame(
+ ((UnenhancedSubtype) un).getRelated(),
+ ((UnenhancedSubtype) copy).getRelated());
+ assertEquals(
+ ((UnenhancedSubtype) un).getRelated().getId(),
+ ((UnenhancedSubtype) copy).getRelated().getId());
+ }
+
+ assertFalse(em.isDetached(un));
+ assertTrue(em.isDetached(copy));
+
+ /*
+ ##### need to make detachment algorithm in ReflectingPC smarter
+ // ensure that remove() cannot be invoked on a detached instance
+ try {
+ em.getTransaction().begin();
+ em.remove(copy);
+ fail("remove() cannot be invoked on detached instance");
+ } catch (IllegalArgumentException e) {
+ em.getTransaction().rollback();
+ }
+ */
+
+ copy.setStringField("offline update");
+
+ em.getTransaction().begin();
+ assertSame(un, em.merge(copy));
+ assertTrue(em.isDirty(un));
+ assertEquals("offline update", un.getStringField());
+ em.getTransaction().commit();
+ }
+
+ public void testListenersOnUserDefinedInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ listenerHelper(true, false);
+ }
+
+ public void testListenersOnUserDefinedSubclassInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ listenerHelper(true, true);
+ }
+
+ public void testListenersOnOpenJPADefinedInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ listenerHelper(false, false);
+ }
+
+ public void testListenersOnOpenJPADefinedSubclassInstance()
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ listenerHelper(false, true);
+ }
+
+ private void listenerHelper(boolean userDefined, boolean sub)
+ throws IOException, ClassNotFoundException, CloneNotSupportedException {
+ ListenerImpl listener = new ListenerImpl();
+ emf.addLifecycleListener(listener, (Class[]) null);
+ OpenJPAEntityManager em = emf.createEntityManager();
+ UnenhancedType un = newInstance(sub);
+ em.getTransaction().begin();
+ em.persist(un);
+ em.getTransaction().commit();
+
+ if (!userDefined) {
+ em.close();
+ em = emf.createEntityManager();
+ }
+
+ listener.invoked = false;
+
+ un = em.find(getUnenhancedClass(), un.getId());
+ em.getTransaction().begin();
+ un.setStringField("updated");
+ em.getTransaction().commit();
+ assertTrue(listener.invoked);
+ em.close();
+
+ assertEquals("updated", listener.stringField);
+ }
+
+ public void testGetMetaDataOfSubtype() {
+ ClassMetaData meta = JPAFacadeHelper.getMetaData(emf,
+ getUnenhancedClass());
+ List<Class> subs = ManagedClassSubclasser.prepareUnenhancedClasses(
+ emf.getConfiguration(),
+ Collections.singleton(getUnenhancedClass()), null);
+ assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
+
+ meta = JPAFacadeHelper.getMetaData(emf, getUnenhancedSubclass());
+ subs = ManagedClassSubclasser.prepareUnenhancedClasses(
+ emf.getConfiguration(),
+ Collections.singleton(getUnenhancedSubclass()), null);
+ assertSame(meta, JPAFacadeHelper.getMetaData(emf, subs.get(0)));
+ }
+
+ private class ListenerImpl
+ extends AbstractLifecycleListener {
+
+ String stringField;
+ boolean invoked;
+
+ @Override
+ public void afterStore(LifecycleEvent event) {
+ invoked = true;
+ stringField = ((UnenhancedType) event.getSource()).getStringField();
+ }
+ }
}
\ No newline at end of file
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/AbstractUnenhancedClassTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java?rev=889871&view=auto
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java (added)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java Sat Dec 12 00:50:58 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.jdbc.persistence.classcriteria;
+
+import java.util.Collection;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "ARTIST")
+public class Artist {
+ @Id
+ @Column(name = "NAME")
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ if (name == null || name.trim().length() == 0)
+ throw new IllegalArgumentException("null or empty name not allowed");
+ this.name = name;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "artist1")
+ public Collection<Book> books;
+
+ public Collection<Book> getBooks() {
+ return books;
+ }
+
+ public void setBooks(Collection<Book> books) {
+ this.books = books;
+ }
+
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "artist")
+ public Collection<Movie> movies;
+
+ public Collection<Movie> getMovies() {
+ return movies;
+ }
+
+ public void setMovies(Collection<Movie> movies) {
+ this.movies = movies;
+ }
+
+ public Artist() {
+ }
+
+ public Artist(String name) {
+ this.name = name;
+ }
+}
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Artist.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java?rev=889871&view=auto
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java (added)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java Sat Dec 12 00:50:58 2009
@@ -0,0 +1,62 @@
+/*
+ * 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.jdbc.persistence.classcriteria;
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorValue(value = "BOOK")
+public class Book extends Item {
+ private static final long serialVersionUID = 7150584274453979159L;
+
+ @Column(name = "PAGE_COUNT")
+ private int pageCount;
+
+ @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @Column(name = "ARTIST")
+ private Artist artist1;
+
+ public Book() {
+ super();
+ }
+
+ public Book(String title) {
+ super(title);
+ }
+
+ public int getPageCount() {
+ return pageCount;
+ }
+
+ public void setPageCount(int d) {
+ if (d < 0) {
+ throw new IllegalArgumentException("Invalid page count " + d + " for " + this);
+ }
+
+ pageCount = d;
+ }
+
+ public Artist getArtist() {
+ return artist1;
+ }
+
+ public void setArtist(Artist artist1) {
+ this.artist1 = artist1;
+ }
+}
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Book.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java?rev=889871&view=auto
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java (added)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java Sat Dec 12 00:50:58 2009
@@ -0,0 +1,96 @@
+/*
+ * 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.jdbc.persistence.classcriteria;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+@Entity
+@Table(name = "ITEMTABLE")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "ITEM_TYPE", discriminatorType = DiscriminatorType.STRING, length = 8)
+public class Item implements Serializable {
+ private static final long serialVersionUID = 3375001494950016360L;
+
+ @Id
+ @GeneratedValue
+ @Column(name = "UID1")
+ private int id;
+
+ @Column
+ private String title;
+
+ @Transient
+ private float rating;
+
+ protected Item() {
+ super();
+ }
+
+ public Item(String title) {
+ super();
+ this.title = title;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ if (title == null || title.trim().length() == 0) {
+ throw new IllegalArgumentException("null or empty title not allowed");
+ }
+ this.title = title;
+ }
+
+ public float getRating() {
+ return rating;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final Item item = (Item) o;
+
+ return id == item.id;
+ }
+
+ public int hashCode() {
+ return id;
+ }
+}
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Item.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java?rev=889871&view=auto
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java (added)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java Sat Dec 12 00:50:58 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.jdbc.persistence.classcriteria;
+
+import javax.persistence.*;
+
+@Entity
+@DiscriminatorValue(value = "MOVIE")
+public class Movie extends Item {
+ private static final long serialVersionUID = 5263476520279196994L;
+
+ @Column(name = "DURATION")
+ private Integer duration;
+
+ @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @Column(name = "ARTIST")
+ private Artist artist;
+
+ public Movie() {
+ super();
+ }
+
+ public Movie(String title) {
+ super(title);
+ }
+
+ public Integer getDuration() {
+ return duration;
+ }
+
+ public void setDuration(int d) {
+ if (d < 0) {
+ throw new IllegalArgumentException("Invalid duration " + d + " for " + this);
+ }
+
+ duration = d;
+ }
+
+ public Artist getArtist() {
+ return artist;
+ }
+
+ public void setArtist(Artist artist) {
+ this.artist = artist;
+ }
+
+}
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/Movie.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java?rev=889871&view=auto
==============================================================================
--- openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java (added)
+++ openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java Sat Dec 12 00:50:58 2009
@@ -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.jdbc.persistence.classcriteria;
+
+import java.util.Collection;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestQuerySubclass extends SingleEMFTestCase {
+
+ private OpenJPAEntityManager em;
+
+ public void setUp() {
+ setUp("openjpa.Compatibility",
+ "superclassDiscriminatorStrategyByDefault=true", CLEAR_TABLES,
+ Artist.class, Book.class, Item.class, Movie.class);
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Book b = new Book("book");
+ Movie m = new Movie("movie");
+ Artist a = new Artist("Herman Hess");
+ b.setArtist(a);
+ m.setArtist(a);
+ em.persist(a);
+ em.persist(b);
+ em.persist(m);
+ em.getTransaction().commit();
+
+ }
+
+ public void testQuery() {
+ Collection<Book> books = null;
+ Collection<Movie> movies = null;
+ em = emf.createEntityManager();
+ Artist artist = em.find(Artist.class, "Herman Hess");
+ if (artist == null) {
+ System.out.println("No artist found with ID Herman Hess");
+ }
+ else {
+ books = artist.getBooks();
+ movies = artist.getMovies();
+ }
+ assertEquals(1, books.size());
+ assertEquals(1, movies.size());
+ }
+
+ public void tearDown() throws Exception {
+ }
+}
Propchange: openjpa/branches/1.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/persistence/classcriteria/TestQuerySubclass.java
------------------------------------------------------------------------------
svn:eol-style = native