CMR Example
I have only found one way to use CMR with JBoss. That is to
use:
/**
* @ejb:relation name="Branch-Leaves" role-name="BranchHasLeaves"
* target-role-name="LeavesFromBranch"
* target-cascade-delete="no" target-ejb="Leaves"
* @jboss:target-relation related-pk-field="branchID" fk-column="BranchID"
**/
public abstract java.util.Collection GetLeaves();
The problem with this solution is that this will create a field in the
target EJB, database table named BranchID. The target EJB cannot be defined
with getter, setter, finder or selector functions for BranchID. Creating
an extra BranchID in the target EJB will create the error:
org.jboss.ejb.plugins.cmp.ejbql.UnknownPathException: Unknown terminal field:
To get the branches, use:
BranchLocal bl;
java.util.Collection col = bl.getLeaves();
LeaveLocal ll = (LeaveLocal)col.next();
To set the branches, use:
BranchLocal bl;
LeaveLocalHome llh = (DataStreamLocalHome)lContext.lookup("LeaveLocal");
LeaveData lData = new LeaveData();
col.add(llh.create(lData));
bl.setLeaves(col);
The following shows examples of tags and errors
According to documentation I found on the JBoss forum site,
"JBoss 3.0 supports J2EE 1.3, EJB is in version 2.0 with full support for CMR."
I don't know if this answers the problems I am seeing below for CMR.
Example 1 (Works)
Source:
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:target-relation related-pk-field="runID" fk-column="RunID"
Result:
This works as long as the fk-column (RunID) is not already declared in
the "many" (DataStream) object. If the fk-column is already defined,
then the following error will display.
"org.jboss.deployment.DeploymentException: Error while creating table;
- nested throwable: (java.sql.SQLException: Invalid argument value,
message from server: "Duplicate column name 'RunID'")]
Example 2
Source:
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
Result:
Atleast one role of a foreign-key mapped relationship must have key fields
Example 3
The following source has variations such as <fk-constraint>no</fk-constraint>,
but the key-fields are all defined on the same side.
Source:
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:relation related-pk-field="runID"
Or:
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:relation related-pk-field="runID" fk-constraint="no"
Or
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:relation fk-constraint="no"
@jboss:target-relation related-pk-field="runID"
Or
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:target-relation related-pk-field="runID" fk-constraint="no"
Result:
Role: DataStreamsInRun with multiplicity many using foreign-key mapping is not
allowed to have key-fields. JBossCmp-JDBC.xml:
Generated XML:
<relationships><ejb-relation><ejb-relation-name>Runs-DataStreams</ejb-relation-name><foreign-key-mapping/>
<ejb-relationship-role>
<ejb-relationship-role-name>RunHasDataStreams</ejb-relationship-role-name>
<key-fields/></ejb-relationship-role><ejb-relationship-role>
<ejb-relationship-role-name>DataStreamsInRun</ejb-relationship-role-name>
<key-fields><key-field><field-name>runID</field-name><column-name></column-name>
</key-field></key-fields></ejb-relationship-role></ejb-relation>
<ejb-relation><ejb-relation-name>Sequences-Runs</ejb-relation-name><foreign-key-mapping/>
<ejb-relationship-role>
<ejb-relationship-role-name>SequenceHasRuns</ejb-relationship-role-name>
<key-fields><key-field><field-name>sequenceID</field-name><column-name>SequenceID</column-name>
</key-field></key-fields></ejb-relationship-role><ejb-relationship-role>
<ejb-relationship-role-name>RunsInSequence</ejb-relationship-role-name>
<key-fields/></ejb-relationship-role></ejb-relation></relationships>
Example 4
Source:
@ejb:relation name="Runs-DataStreams" role-name="RunHasDataStreams"
target-role-name="DataStreamsInRun"
target-cascade-delete="no" target-ejb="DataStream"
@jboss:target-relation related-pk-field="runID"
Result:
Error while creating table; - nested throwable: (java.sql.SQLException:
Syntax error or access violation, message from server:
"You have an error in your SQL syntax near
'BIGINT, CONSTRAINT pk_DataStream PRIMARY KEY (DataStreamID))' at line 1")]
JBossCmp-JDBC.xml:
Generated XML:
<relationships><ejb-relation><ejb-relation-name>Runs-DataStreams</ejb-relation-name><foreign-key-mapping/>
<ejb-relationship-role><ejb-relationship-role-name>RunHasDataStreams</ejb-relationship-role-name>
<key-fields><key-field><field-name>runID</field-name><column-name></column-name>
</key-field></key-fields></ejb-relationship-role>
<ejb-relationship-role><ejb-relationship-role-name>DataStreamsInRun</ejb-relationship-role-name>
<key-fields/></ejb-relationship-role></ejb-relation>
<ejb-relation><ejb-relation-name>Sequences-Runs</ejb-relation-name><foreign-key-mapping/>
<ejb-relationship-role><ejb-relationship-role-name>SequenceHasRuns</ejb-relationship-role-name>
<key-fields><key-field><field-name>sequenceID</field-name><column-name>SequenceID</column-name>
</key-field></key-fields></ejb-relationship-role>
<ejb-relationship-role><ejb-relationship-role-name>RunsInSequence</ejb-relationship-role-name>
<key-fields/></ejb-relationship-role></ejb-relation></relationships>