CMP, CMR, FK and Referential Integrity

Discussions

EJB programming & troubleshooting: CMP, CMR, FK and Referential Integrity

  1. CMP, CMR, FK and Referential Integrity (8 messages)

    Hi,
    I need some help on understanding CMR and FK that do not accept nulls.
    I have a composition in my model. It is also implemented in my database (Oracle 9i).
    Whenever I try to call the create() methodo on the child entity I receive a SQL Exception telling that I cannot insert null values in my FK.
    If I try to set the value of the FK "by hand" I receive the following..

    javax.ejb.TransactionRolledbackLocalException: EJB Exception:; nested exception is: javax.ejb.EJBException: [EJB:010145]When a cmp-field and a cmr-field (relationship) are mapped to the same column, the setXXX method for the cmp-field may not be called. The cmp-field is read-only.

    What should I do?
    Thank you in advance...
    André
  2. Hi,I need some help on understanding CMR and FK that do not accept nulls.I have a composition in my model. It is also implemented in my database (Oracle 9i).Whenever I try to call the create() methodo on the child entity I receive a SQL Exception telling that I cannot insert null values in my FK.If I try to set the value of the FK "by hand" I receive the following..javax.ejb.TransactionRolledbackLocalException: EJB Exception:; nested exception is: javax.ejb.EJBException: [EJB:010145]When a cmp-field and a cmr-field (relationship) are mapped to the same column, the setXXX method for the cmp-field may not be called. The cmp-field is read-only.What should I do?Thank you in advance...André


    From the error message it looks like that you are using weblogic. If that is the case then the following will work (others I don't know) -

    Do not use the CMP setXXX method to set the FK field. To set the FK use the CMR setter field in ejbPostCreate - this means you will need an EJB object representing the other entity bean. Note that if you use the CMR setter in ejbCreate it will not work. Detailed explanation is here -

    http://e-docs.bea.com/wls/docs81/faq/ejb.html

    Go to the CMP entity beans section there.
  3. To set the FK use the CMR setter field in ejbPostCreate

    This is correct, because until ejbCreate() is completed, the no INSERT took place in the DB for the principal registry (the "target" of the FK); once it's completed, you can INSERT the registry with the FK... and ejbPostCreate is where you should do it.

    Cheers and happy coding,
    Martin
  4. Hi KB,
    Thank you for your response!
    Yes, I'm using wls 8.1 sp4.
    I'm sorry, but can you explain to me how to call the CMR setter method and how to get an EJB object representing the other entity bean?

    I´m trying to call de getXXX.add(childBean), since this getXXX in the parent returns a Collection.
    Is that correct?

    thanks again,
    Andre
  5. Hi KB,Thank you for your response!Yes, I'm using wls 8.1 sp4.I'm sorry, but can you explain to me how to call the CMR setter method and how to get an EJB object representing the other entity bean?I´m trying to call de getXXX.add(childBean), since this getXXX in the parent returns a Collection.Is that correct?thanks again,Andre


    Lets take an example here -

    We have two entity beans Order (in ORDER table) and LineItem (in ITEM table). In ITEM there is a FK called ORDER_ID which is a primary key in ORDER table. One order may have one or more line items.

    In the Order entity bean we have the CMR getter/setter declared as -

    public abstract Collection getLineItems();
    public abstract void setLineItems(Collection lineItems);

    In the LineItem entity bean we have the CMR getter/setter declared as -

    public abstract OrderLocal getOrder();
    public abstract void getOrder(OrderLocal order);

    where OrderLocal is the local interface of Order entity bean.


    To create Order (and LineItems) -

    1. Create Order first - create it through ejbCreate. Don't set the CMR field setLineItems(Collection lineItems) now since your line items are not already created.

    2. Now iterate through each of the line items you want to create. Call create on the home object of LineItem and pass as an argument the Order object (OrderLocal) you created in step 1 above.

    So ejbCreate method of LineItem may look like :

    public Long ejbCreate (OrderLocal order, ....) throws CreateException
    {
        ....
    }

    where
    LineItemLocal is the local interface of LineItem.
    ... could be other arguments you need


    3. In ejbCreate of LineItem set the CMP fields only. DO NOT set the CMR field.

    4. In ejbPostCreate of LineItem (that takes the same arguments as ejbCreate) call

    setOrder( order); -----> this is where the relationship gets defined. Note that you don't have to do anything in the parent entity bean.

    Hope this helps.
    Kingshuk
  6. Kingshuk,
    Thank you very much for your help!
    I've got everything working fine ...
    I did exactly what you told me, and I just created the beans from a Session Façade.
    Thanks again.
    Andre
  7. Unidirectional relation?[ Go to top ]

    Hello KB,

    I was going through your solution, and it assumes a 2 way 1:N relation, that is, the Order is accessible/settable through the LineItem bean.

    How can we solve this problem if the relation is unidirectional, ie the Order is not navigatable from LineItem?

    Or is it that the relationship directional is a logical concept and we can always code for bidirectional relations for the beans?

    Thank you very much.
    Suteertha
  8. NOT NULL columns[ Go to top ]

    If I have NOT NULL table column, I put it's fields (having setter methods in EJB) in ejbCreate() method.
  9. Hi friends, when i do a relation program i am getting the same error above..but i am not understanding the ans becase i am not a expert in this.. Please help me My problem is i have tow table Order_header (PK po_no) order_detail (PK serial_no,FK po_no) then code below is the one i am using /** * * * <!-- begin-user-doc --> * CMR Field items * * Returns the items * @return the items * * <!-- end-user-doc --> * * <!-- begin-xdoclet-definition --> * @ejb.interface-method * view-type="local" * * @ejb.relation * * name="order_header" * role-name="Order-contains-Items" * target-ejb="OrderDetail" * target-role-name="item-contained-in-order" * target-cascade-delete="yes" * * @weblogic.target-column-map * foreign-key-column="po_no" * key-column="po_no" * * * * * * <!-- end-xdoclet-definition --> * @generated */ public abstract java.util.Collection getItems(); /** * <!-- begin-user-doc --> * Sets the Items * * @param java.util.Collection the new items value * <!-- end-user-doc --> * * <!-- begin-xdoclet-definition --> * @ejb.interface-method * view-type="local" * <!-- end-xdoclet-definition --> * @generated */ public abstract void setItems(java.util.Collection items); I m getting the error of [java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails] Great gurus please help me priya