1 Reply Latest reply on Jul 27, 2005 9:19 AM by kkokal

    Problem deleting one side of m:n bi-directional CMR

    kkokal

      I have what seems to be a very straight-forward scenario, but I'm experiencing a problem I can't find a solution for.

      Two EJB2 CMP entity beans (generated w/ xdoclet) participate in an m:n bi-directional relationship:
      MSide (backed by DB table 'mside', primary key 'id')
      NSide (backed by DB table 'nside', primary key 'id')

      The relation table in the DB ('mn') contains constrained FK columns mid and nid.

      When I call mside.remove(), I get a RemoveException (DELETE statement conflicted with COLUMN REFERENCE constraint 'FK_MN_MSide'. The conflict occurred in database 'jboss_dev', table 'MN', column 'mid'.) because the CMP engine is trying to delete the MSide row before it deletes the relationship row from the 'MN' table. How do I indicate that the relationship should be deleted first?

      Regards,
      Kevin Kokal


      Environment:
      JBoss 4.0.2
      MS SQL Server
      JTDS 1.1 JDBC driver

      ejb-jar.xml snippet:

      [CDATA[Description for MSide]]
      <display-name>Name for MSide</display-name>
      <ejb-name>MSide</ejb-name>
      test.bugs.deletemanytomany.MSideHome
      test.bugs.deletemanytomany.MSide
      <local-home>test.bugs.deletemanytomany.MSideLocalHome</local-home>
      test.bugs.deletemanytomany.MSideLocal
      <ejb-class>test.bugs.deletemanytomany.MSideCMP</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Long</prim-key-class>
      False
      <cmp-version>2.x</cmp-version>
      <abstract-schema-name>MSide</abstract-schema-name>
      <cmp-field >
      [CDATA[]]
      <field-name>id</field-name>
      </cmp-field>
      <primkey-field>id</primkey-field>



      [CDATA[Description for NSide]]
      <display-name>Name for NSide</display-name>
      <ejb-name>NSide</ejb-name>
      test.bugs.deletemanytomany.NSideHome
      test.bugs.deletemanytomany.NSide
      <local-home>test.bugs.deletemanytomany.NSideLocalHome</local-home>
      test.bugs.deletemanytomany.NSideLocal
      <ejb-class>test.bugs.deletemanytomany.NSideCMP</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Long</prim-key-class>
      False
      <cmp-version>2.x</cmp-version>
      <abstract-schema-name>NSide</abstract-schema-name>
      <cmp-field >
      [CDATA[]]
      <field-name>id</field-name>
      </cmp-field>
      <primkey-field>id</primkey-field>


      <ejb-relation >
      <ejb-relation-name>m-n</ejb-relation-name>
      <ejb-relationship-role >
      <ejb-relationship-role-name>theNSide</ejb-relationship-role-name>
      Many
      <relationship-role-source >
      <ejb-name>NSide</ejb-name>
      </relationship-role-source>
      <cmr-field >
      <cmr-field-name>theMSides</cmr-field-name>
      <cmr-field-type>java.util.Collection</cmr-field-type>
      </cmr-field>
      </ejb-relationship-role>

      <ejb-relationship-role >
      <ejb-relationship-role-name>theMSide</ejb-relationship-role-name>
      Many
      <relationship-role-source >
      <ejb-name>MSide</ejb-name>
      </relationship-role-source>
      <cmr-field >
      <cmr-field-name>theNSides</cmr-field-name>
      <cmr-field-type>java.util.Collection</cmr-field-type>
      </cmr-field>
      </ejb-relationship-role>

      </ejb-relation>


      jboss.xml:

      <ejb-name>NSide</ejb-name>
      <jndi-name>ejb/NSide</jndi-name>
      <local-jndi-name>NSideLocal</local-jndi-name>
      <configuration-name>Standard CMP 2.x EntityBean</configuration-name>
      <method-attributes></method-attributes>



      <ejb-name>MSide</ejb-name>
      <jndi-name>ejb/MSide</jndi-name>
      <local-jndi-name>MSideLocal</local-jndi-name>
      <configuration-name>Standard CMP 2.x EntityBean</configuration-name>
      <method-attributes></method-attributes>



      jbosscmp-jdbc.xml:
      <ejb-relation>
      <ejb-relation-name>m-n</ejb-relation-name>
      <relation-table-mapping>
      <table-name>mn</table-name>
      <create-table>false</create-table>
      <remove-table>false</remove-table>
      </relation-table-mapping>

      <ejb-relationship-role>
      <ejb-relationship-role-name>theNSide</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>id</field-name>
      <column-name>nId</column-name>
      </key-field>
      </key-fields>

      </ejb-relationship-role>
      <ejb-relationship-role>
      <ejb-relationship-role-name>theMSide</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>id</field-name>
      <column-name>mId</column-name>
      </key-field>
      </key-fields>

      </ejb-relationship-role>
      </ejb-relation>

      IMPORTANT:
      Note that the "Standard CMP 2.x EntityBean" specified in jboss.xml is NOT the default config of the same name, but rather a renamed copy of the Instance Per Transaction config. Here is the config from standardjboss.xml:

      <container-configuration>
      <container-name>Standard CMP 2.x EntityBean</container-name>
      <!--container-name>Instance Per Transaction CMP 2.x EntityBean</container-name-->
      <call-logging>true</call-logging>
      <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
      <sync-on-commit-only>true</sync-on-commit-only>
      <insert-after-ejb-post-create>true</insert-after-ejb-post-create>
      <call-ejb-store-on-clean>true</call-ejb-store-on-clean>
      <container-interceptors>
      org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor
      org.jboss.ejb.plugins.LogInterceptor
      org.jboss.ejb.plugins.SecurityInterceptor
      org.jboss.ejb.plugins.TxInterceptorCMT
      org.jboss.ejb.plugins.CallValidationInterceptor
      org.jboss.ejb.plugins.MetricsInterceptor
      org.jboss.ejb.plugins.EntityCreationInterceptor
      org.jboss.ejb.plugins.EntityLockInterceptor
      org.jboss.ejb.plugins.EntityInstanceInterceptor
      org.jboss.ejb.plugins.EntityReentranceInterceptor
      org.jboss.resource.connectionmanager.CachedConnectionInterceptor
      org.jboss.ejb.plugins.EntitySynchronizationInterceptor
      org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor
      </container-interceptors>
      <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool>
      <instance-cache>org.jboss.ejb.plugins.PerTxEntityInstanceCache</instance-cache>
      <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</persistence-manager>
      <locking-policy>org.jboss.ejb.plugins.lock.NoLock</locking-policy>
      <container-cache-conf/>
      <container-pool-conf>
      100
      </container-pool-conf>
      <commit-option>C</commit-option>
      </container-configuration>