Simple (one-column) scenario
----------------------------
Two foreign key fields (of different foreign keys) are
mapped to the same column that is used for a CMP field.
Changing CMP field value so that there is no related
entity for a new foreign key value causes a
StackOverflowError.
The patch:
1. add the following method to JDBCCMRFieldBridge.java
/**
* Sets the foreign key field value and updates CMP
fields this foreign key field
* is mapped to except the dontUpdateThisCMPField
that forced the update of this
* foreign key field.
*/
public void setForeignKey(EntityEnterpriseContext
myCtx,
Object foreignKey,
JDBCCMP2xFieldBridge
dontUpdateThisCMPField)
{
if(!hasForeignKey())
throw new EJBException(getFieldName() + " CMR
field does not have a foreign key to set.");
for(Iterator fkFieldsIter = foreignKeyFields.iterator();
fkFieldsIter.hasNext();)
{
JDBCCMP2xFieldBridge fkField =
(JDBCCMP2xFieldBridge)fkFieldsIter.next();
Object fieldValue = fkField.getPrimaryKeyValue
(foreignKey);
fkField.setInstanceValue(myCtx, fieldValue);
JDBCCMP2xFieldBridge cmpField =
fkField.getCmpFieldIAmMappedTo();
if(cmpField != null && !
cmpField.isPrimaryKeyMember() && cmpField !=
dontUpdateThisCMPField)
cmpField.setInstanceValue(myCtx, fieldValue,
fkField);
}
}
2. JDBCCMP2xFieldBridge.java in
updateFKFieldMappedToMe(...) change
fkFieldMappedToMe.myCMRField.setForeignKey(ctx,
newRelatedId);
to
fkFieldMappedToMe.myCMRField.setForeignKey(ctx,
newRelatedId, this);
Complex (multi-columns) scenario
--------------------------------
The same as above but with more than one column
involved.
There are at least two foreign keys consisting of at least
two foreign key fields. These foreign key fields share the
same columns. And there
are also CMP fields mapped to these same columns.
Changing CMP fields so that for at least one foreign
value there is no related entity causes
StackOverflowError.
No patch for the moment.
alex
Logged In: YES
user_id=543482
attached a testcase
Logged In: YES
user_id=543482
The stack is under control!
Update the foreign key fields only is this CMP field is really
changed.
JDBCCMP2xFieldBridge.java
private void setInstanceValue(EntityEnterpriseContext ctx,
Object value,
JDBCCMP2xFieldBridge
dontUpdateThisFKField,
boolean updateFKFieldsMappedToMe)
{
...
+++ boolean changed = changed(fieldState.value, value);
// update current value
fieldState.value = value;
// update foreign key fields mapped to this CMP field and
// mark their CMR fields as not loaded
+++ if(changed && updateFKFieldsMappedToMe && !
fkFieldsMappedToMe.isEmpty() && ctx.isValid())
updateFKFieldsMappedToMe(ctx, value,
dontUpdateThisFKField);
alex