1 Reply Latest reply on Sep 1, 2004 3:11 AM by Alexey Loubyansky

    Compound PK containing FK

    Andrew May Newbie

      Hi, I know there's been a lot of posts about this before, but I wanted to check that I was doing this right, and I've not been able to find any official documentation...

      I've got a series of entities with attached properties - e.g. identity and identityproperty. The main entity has an id, and the property table has a foreign key (entityid).

      In our original CMP implementation done using JBoss 3.0.0 we weren't able to use the foreign key as part of the primary key on the property table (because that wasn't supported at the time) and had an extra propertyid column as the PK. I've been trying to convert this to having a primary key consisting of the entityid and the name of the property.

      Previously the foreign key column hadn't been declared in my property bean because it was set by the CMR stuff, but I added it so that it could be part of the PK. Here's what I ended up with as the implementation for the property bean:

      public abstract class PropertyBean extends AbstractEntity
      {
       /**
       * Get Id of related Entity (e.g. Identity).
       * Part of Primary Key
       * @ejb:interface-method view-type="local"
       * @ejb:persistent-field
       * @ejb:pk-field
       * @jboss:column-name name="entityid"
       */
       public abstract String getEntityId();
      
       /**
       * @ejb:interface-method view-type="local"
       */
       public abstract void setEntityId(String entityId);
      
       /**
       * CMP get method for Name attribute.
       * @ejb:interface-method view-type="local"
       * @ejb:persistent-field
       * @ejb:pk-field
       * @jboss:column-name name="name"
       */
       public abstract String getName();
      
       /**
       * CMP set method for Name attribute.
       * @ejb:transaction type="Mandatory"
       */
       public abstract void setName(String name);
      
       /**
       * CMP get method for Value attribute.
       * @ejb:interface-method view-type="local"
       * @ejb:persistent-field
       * @jboss:column-name name="value"
       */
       public abstract String getValue();
      
       /**
       * CMP set method for Value attribute.
       * @ejb:interface-method view-type="local"
       * @ejb:transaction type="Mandatory"
       */
       public abstract void setValue(String value);
      
       /**
       * Create method for Entity.
       * @ejb:create-method view-type="local"
       * @ejb:transaction type="Mandatory"
       */
       public PropertyPK ejbCreate(String entityId, String name, String value) throws javax.ejb.CreateException
       {
       setEntityId(entityId);
       setName(name);
       setValue(value);
       return null;
       }
      
       public void ejbPostCreate(String entityId, String name, String value)
       {
       }
      


      I started out without the entityId in ejbCreate() because I was expecting it to be set when the property was added to the parent's CMR collection, but this gave me database errors (the not null constraint on this part of the PK). I tried running with <insert-after-ejb-post-create>true</insert-after-ejb-post-create> in the container configuration, but the entityId was still null in ejbPostCreate (or at least in then PropertyPK I got from the EntityContext).

      So I ended up adding entityId to ejbCreate and setting it. This works, but I'm not sure whether it's the correct thing to do, because in theory I could end up adding it to the CMR collection of a different parent after creating it, and then I don't know what would happen to entityId.

      I'd appreciate it if I could have some feedback about whether I'm doing the right or wrong thing, and if I'm doing this wrong, could someone please point me in the right direction.

      Thanks,
      Andrew

        • 1. Re: Compound PK containing FK
          Alexey Loubyansky Master

          This is the right thing to do. Regardless of pk/fk mapping the valid primary value should be available after ejbCreate and before ejbPostCreate.
          If a foreign key field is mapped to a primary key column the relationship can only be established by related instance creation and destroyed by instance removal. Since pk is not allowed to be changed, if you attempt to change the relationship which involves changing the pk value, you'll get an exception.