mirror of https://github.com/apache/openjpa.git
OPENJPA-1061 merging patch provided by Jody Grassel to trunk
modified: openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java modified: openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@789519 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1fce44737b
commit
03d9e24bc6
|
@ -1138,9 +1138,15 @@ public class PCEnhancer {
|
|||
addCopyKeyFieldsToObjectIdMethod(false);
|
||||
addCopyKeyFieldsFromObjectIdMethod(true);
|
||||
addCopyKeyFieldsFromObjectIdMethod(false);
|
||||
if (_meta.hasAbstractPKField() == true) {
|
||||
addGetIDOwningClass();
|
||||
}
|
||||
addNewObjectIdInstanceMethod(true);
|
||||
addNewObjectIdInstanceMethod(false);
|
||||
}
|
||||
else if (_meta.hasPKFieldsFromAbstractClass()){
|
||||
addGetIDOwningClass();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2536,26 +2542,28 @@ public class PCEnhancer {
|
|||
// new ObjectId (cls, oid)
|
||||
code.anew().setType(ObjectId.class);
|
||||
code.dup();
|
||||
if(_meta.isEmbeddedOnly()) {
|
||||
if(_meta.isEmbeddedOnly() || _meta.hasAbstractPKField() == true) {
|
||||
code.aload().setThis();
|
||||
code.invokevirtual().setMethod(Object.class, "getClass",
|
||||
code.invokevirtual().setMethod(PRE + "GetIDOwningClass",
|
||||
Class.class, null);
|
||||
}else
|
||||
} else {
|
||||
code.classconstant().setClass(getType(_meta));
|
||||
}
|
||||
}
|
||||
|
||||
// new <oid class> ();
|
||||
code.anew().setType(oidType);
|
||||
code.dup();
|
||||
if (_meta.isOpenJPAIdentity() || (obj && usesClsString ==
|
||||
Boolean.TRUE)) {
|
||||
if(_meta.isEmbeddedOnly()) {
|
||||
if(_meta.isEmbeddedOnly() || _meta.hasAbstractPKField() == true ) {
|
||||
code.aload().setThis();
|
||||
code.invokevirtual().setMethod(Object.class, "getClass",
|
||||
code.invokevirtual().setMethod(PRE + "GetIDOwningClass",
|
||||
Class.class, null);
|
||||
}else
|
||||
}else {
|
||||
code.classconstant().setClass(getType(_meta));
|
||||
}
|
||||
}
|
||||
if (obj) {
|
||||
code.aload().setParam(0);
|
||||
code.checkcast().setType(String.class);
|
||||
|
@ -4624,4 +4632,16 @@ public class PCEnhancer {
|
|||
public void run (BCClass bc, ClassMetaData meta);
|
||||
public boolean skipEnhance(BCMethod m);
|
||||
}
|
||||
|
||||
private void addGetIDOwningClass() throws NoSuchMethodException {
|
||||
BCMethod method = _pc.declareMethod(PRE + "GetIDOwningClass",
|
||||
Class.class, null);
|
||||
Code code = method.getCode(true);
|
||||
|
||||
code.classconstant().setClass(getType(_meta));
|
||||
code.areturn();
|
||||
|
||||
code.calculateMaxStack();
|
||||
code.calculateMaxLocals();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,8 @@ public class ClassMetaData
|
|||
private boolean _intercepting = false;
|
||||
private Boolean _useIdClassFromParent = null;
|
||||
private boolean _abstract = false;
|
||||
private Boolean _hasAbstractPKField = null;
|
||||
private Boolean _hasPKFieldsFromAbstractClass = null;
|
||||
|
||||
/**
|
||||
* Constructor. Supply described type and repository.
|
||||
|
@ -2593,4 +2595,78 @@ public class ClassMetaData
|
|||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to determine if the pcType modeled by
|
||||
* this ClassMetaData object is both abstract and declares PKFields. This
|
||||
* method is used by the PCEnhancer to determine if special handling is
|
||||
* required.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasAbstractPKField() {
|
||||
if (_hasAbstractPKField != null) {
|
||||
return _hasAbstractPKField.booleanValue();
|
||||
}
|
||||
|
||||
// Default to false, set to true only if this type is abstract and
|
||||
// declares a PKField.
|
||||
_hasAbstractPKField = Boolean.FALSE;
|
||||
|
||||
if (isAbstract() == true) {
|
||||
FieldMetaData[] declaredFields = getDeclaredFields();
|
||||
if (declaredFields != null && declaredFields.length != 0) {
|
||||
for (FieldMetaData fmd : declaredFields) {
|
||||
if (fmd.isPrimaryKey()) {
|
||||
_hasAbstractPKField = Boolean.TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _hasAbstractPKField.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to determine if this type is a direct
|
||||
* decendent of an abstract type declaring PKFields. Returns true if there
|
||||
* are no pcTypes mapped to a table between this type and an abstract pcType
|
||||
* declaring PKFields. Returns false if there no such abstract pcTypes in
|
||||
* the inheritance hierarchy or if there are any pcTypes mapped to tables in
|
||||
* between the type represented by this ClassMetaData object and the
|
||||
* abstract pcType declaring PKFields.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasPKFieldsFromAbstractClass() {
|
||||
if (_hasPKFieldsFromAbstractClass != null) {
|
||||
return _hasPKFieldsFromAbstractClass.booleanValue();
|
||||
}
|
||||
|
||||
// Default to FALSE, until proven true.
|
||||
_hasPKFieldsFromAbstractClass = Boolean.FALSE;
|
||||
|
||||
FieldMetaData[] pkFields = getPrimaryKeyFields();
|
||||
for (FieldMetaData fmd : pkFields) {
|
||||
ClassMetaData fmdDMDA = fmd.getDeclaringMetaData();
|
||||
if (fmdDMDA.isAbstract()) {
|
||||
ClassMetaData cmd = getPCSuperclassMetaData();
|
||||
while (cmd != fmdDMDA) {
|
||||
if (fmdDMDA.isAbstract()) {
|
||||
cmd = cmd.getPCSuperclassMetaData();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmd == fmdDMDA) {
|
||||
_hasPKFieldsFromAbstractClass = Boolean.TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _hasPKFieldsFromAbstractClass.booleanValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue