From ef56ba140684756696414a848f0d5179c950af07 Mon Sep 17 00:00:00 2001 From: Patrick Linskey Date: Wed, 22 Aug 2007 00:06:16 +0000 Subject: [PATCH] OPENJPA-293. Better validation that the persistent types to subclass have properly been found. git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.0.0@568337 13f79535-47bb-0310-9956-ffa450edef68 --- .../enhance/ManagedClassSubclasser.java | 46 +++++++++++++++++++ .../openjpa/enhance/localizer.properties | 5 +- .../enhance/TestRelationToUnlistedClass.java | 38 +++++++++++++++ .../enhance/UnenhancedUnlistedClass.java | 28 +++++++++++ .../enhance/UnenhancedUnlistedReferer.java | 32 +++++++++++++ .../persistence/test/SingleEMTestCase.java | 2 +- 6 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java diff --git a/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java b/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java index 09d08ded5..c0c8ae33a 100644 --- a/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java +++ b/openjpa-kernel-5/src/main/java/org/apache/openjpa/enhance/ManagedClassSubclasser.java @@ -23,9 +23,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.openjpa.conf.OpenJPAConfiguration; import org.apache.openjpa.lib.log.Log; @@ -36,6 +38,7 @@ import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.util.GeneratedClasses; +import org.apache.openjpa.util.ImplHelper; import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.UserException; import serp.bytecode.BCClass; @@ -101,6 +104,7 @@ public class ManagedClassSubclasser { final Map map = new HashMap(); final List subs = new ArrayList(classes.size()); final List ints = new ArrayList(classes.size()); + Set unspecified = null; for (Iterator iter = classes.iterator(); iter.hasNext(); ) { final Class cls = (Class) iter.next(); final PCEnhancer enhancer = new PCEnhancer(conf, cls); @@ -123,6 +127,9 @@ public class ManagedClassSubclasser { // reconfiguration at the end of this method. configureMetaData(enhancer.getMetaData(), conf, redefine, false); + unspecified = collectRelatedUnspecifiedTypes(enhancer.getMetaData(), + classes, unspecified); + enhancer.run(); try { enhancer.record(); @@ -132,6 +139,10 @@ public class ManagedClassSubclasser { } } + if (unspecified != null && !unspecified.isEmpty()) + throw new UserException(_loc.get("unspecified-unenhanced-types", + classes, unspecified)); + ClassRedefiner.redefineClasses(conf, map); for (Class cls : map.keySet()) { setIntercepting(conf, envLoader, cls); @@ -145,6 +156,41 @@ public class ManagedClassSubclasser { return subs; } + private static Set collectRelatedUnspecifiedTypes(ClassMetaData meta, + Collection classes, Set unspecified) { + unspecified = collectUnspecifiedType(meta.getPCSuperclass(), classes, + unspecified); + + for (FieldMetaData fmd : meta.getFields()) { + if (fmd.isTransient()) + continue; + if (fmd.isTypePC()) + unspecified = collectUnspecifiedType(fmd.getType(), classes, + unspecified); + if (fmd.getElement() != null && fmd.getElement().isTypePC()) + unspecified = collectUnspecifiedType(fmd.getElement().getType(), + classes, unspecified); + if (fmd.getKey() != null && fmd.getKey().isTypePC()) + unspecified = collectUnspecifiedType(fmd.getKey().getType(), + classes, unspecified); + if (fmd.getValue() != null && fmd.getValue().isTypePC()) + unspecified = collectUnspecifiedType(fmd.getValue().getType(), + classes, unspecified); + } + return unspecified; + } + + private static Set collectUnspecifiedType(Class cls, + Collection classes, Set unspecified) { + if (cls != null && !classes.contains(cls) + && !ImplHelper.isManagedType(null, cls)) { + if (unspecified == null) + unspecified = new HashSet(); + unspecified.add(cls); + } + return unspecified; + } + private static void configureMetaData(OpenJPAConfiguration conf, ClassLoader envLoader, Class cls, boolean redefineAvailable) { ClassMetaData meta = conf.getMetaDataRepositoryInstance() diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties index c1e12f2b0..29c140657 100644 --- a/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties +++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties @@ -194,4 +194,7 @@ subclasser-fetch-group-override: The field {1} in type {0} is configured to be \ lazily loaded, but lazy loading is not available for classes that use field\ access when not running the OpenJPA enhancer or when dynamic class \ redefinition is not available. -no-accessor: Could not find method called {0} in type {1}. \ No newline at end of file +no-accessor: Could not find method called {0} in type {1}. +unspecified-unenhanced-types: One or more of the types in {0} have relations \ + to other unenhanced types that were not specified. These unspecified types \ + are: {1} \ No newline at end of file diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java new file mode 100644 index 000000000..eeb5a4629 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestRelationToUnlistedClass.java @@ -0,0 +1,38 @@ +/* + * 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 org.apache.openjpa.persistence.test.SingleEMFTestCase; + +public class TestRelationToUnlistedClass + extends SingleEMFTestCase { + + public void setUp() { + setUp(UnenhancedUnlistedReferer.class, CLEAR_TABLES); + } + + public void testRelationToUnlistedClass() { + try { + emf.createEntityManager().close(); + fail("should not be able to initialize system"); + } catch (Exception e) { + assertTrue(e.getMessage().startsWith("One or more of the types")); + } + } +} \ No newline at end of file diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java new file mode 100644 index 000000000..5ae5e07d0 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedClass.java @@ -0,0 +1,28 @@ +/* + * 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 javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class UnenhancedUnlistedClass { + @Id + private int id; +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java new file mode 100644 index 000000000..e520fe5ec --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/UnenhancedUnlistedReferer.java @@ -0,0 +1,32 @@ +/* + * 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 javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class UnenhancedUnlistedReferer { + @Id + private int id; + + @OneToOne + private UnenhancedUnlistedClass other; +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMTestCase.java index 758ab70b4..08cdc9e90 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMTestCase.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMTestCase.java @@ -48,7 +48,7 @@ public abstract class SingleEMTestCase } @Override - public void tearDown() { + public void tearDown() throws Exception { rollback(); close(); super.tearDown();