1 Reply Latest reply on Aug 8, 2003 11:55 PM by radl01

    1:M CMR Problem: Foreign Key Constraints (Again)

      FYI: The following describes a problem I encountered today and the solution to the problem. At its root, the problem resulted the interaction between foreign-key constraints on a database and JBoss' implementation of CMP.

      Two EJB 2.0 EntityBeans (A, B) are involved in a bidirectional 1:M relationship. I know I can specify cascade-delete in the DD, but I want to take some other actions using the owned Set before removing the beans and then removing the owner bean.

      The problem is this: When I retrieve the set of B by calling a CMR accessor method on A, the B entities only contain the PK of the owned objects and the CMR field is null. Trying to remove the B entity, or even doing a findByPrimaryKey() for the B entity, results in a database exception because the required foreign key is empty.

      Solution:

      I also keep a CMP field on B to hold A's primary key to satisfy the foreign-key database constraint. (I don't like having to do this, but that's a related story dealing with ejbCreate. :-) I found, if I set the foreign-key CMP field before attempting the delete, the database is satisfied that I'm not violating a FK relationship.

      Here's some sample code illustrating the situation:

      -------------------
      // delete a user and associated access records
      public void deleteApplicationUser(Integer pk) throws ModelException {
      try {
      ApplicationUserLocal userLocal = this.applicationUserHome.findByPrimaryKey(pk);

      AccessHistoryLocal accessHistoryLocal;
      Iterator iter = userLocal.getAccessHistory().iterator();
      while (iter.hasNext()) {
      accessHistoryLocal = (AccessHistoryLocal) iter.next();
      iter.remove();

      // *** Next line is required to satisfy db fk constraint ***
      accessHistoryLocal.setApplicationUserFK(pk);

      // do some things with access history data before deleting
      // ...

      // remove access history record
      accessHistoryLocal.remove();
      }

      userLocal.remove();
      } catch (FinderException exc) {
      //...
      } catch (RemoveException exc) {
      //...
      }
      }
      -------------------

      It really bugs me that I have to manage these foreign key issues when using JBoss' CMP. First, I had to create FK CMP fields that get set in ejbCreate() methods. Now, I realize I have to set them whenever I'm retrieving related beans. I probably can configure a read-ahead strategy to ensure the FK is available, but I hate dedicating effort to making the plumbing work. I know J2EE servers deal with database foreign keys differently, and some seem to handle this better than the kludges I have to do with JBoss. It would be a nice enhancement if a future JBoss recognized that often databases will have foreign key constraints, perhaps beyond the control of the Java developers, and handle the foreign key constraint "plumbing" issues for us.

      There's so much to love about JBoss, I hate to be critical, but this has been a real time-waster for me.

        • 1. Re: 1:M CMR Problem: Foreign Key Constraints (Again)
          radl01

          Hi,

          I try to solve the similar problem but with create method (in delete I use cascade delete). I never see ejbPostCreate to be invoke in my 1:m rel. between A and B bean. But in my case I cannot rewrite the code that is running on BES and also on WebSphare OK. The problem is that i have to migrate the same application in to the JBoss server and I don't know how.

          the code is very simple (I write my own but same as in the application)

          A:B (1:m)

          in BBean I have ejbCreate(Integer id, ALocal a) {
          setId(id);
          return null;
          }
          and also ejbPostCreate(Integer id, ALocal a) {
          setA(a);
          }

          I read in some previsous topics that the problem sould be solved by removing NOT NULL constraint from DB. But I cannot change DB model.

          Thanks for any help

          Jan