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
This commit is contained in:
Patrick Linskey 2007-08-22 00:06:16 +00:00
parent dc3615c613
commit ef56ba1406
6 changed files with 149 additions and 2 deletions

View File

@ -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<Class, byte[]> map = new HashMap<Class, byte[]>();
final List subs = new ArrayList(classes.size());
final List ints = new ArrayList(classes.size());
Set<Class> 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<Class> collectRelatedUnspecifiedTypes(ClassMetaData meta,
Collection<? extends Class> classes, Set<Class> 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<Class> collectUnspecifiedType(Class cls,
Collection<? extends Class> classes, Set<Class> unspecified) {
if (cls != null && !classes.contains(cls)
&& !ImplHelper.isManagedType(null, cls)) {
if (unspecified == null)
unspecified = new HashSet<Class>();
unspecified.add(cls);
}
return unspecified;
}
private static void configureMetaData(OpenJPAConfiguration conf,
ClassLoader envLoader, Class cls, boolean redefineAvailable) {
ClassMetaData meta = conf.getMetaDataRepositoryInstance()

View File

@ -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-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}

View File

@ -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"));
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -48,7 +48,7 @@ public abstract class SingleEMTestCase
}
@Override
public void tearDown() {
public void tearDown() throws Exception {
rollback();
close();
super.tearDown();