I am new to CMR in EJB2.0 and am having problems trying to create dependent entity beans with foreign key not null constraints.
Removing constraint in database is not an option, nor is removing NOT NULL tag on the foreign keys, as there are other applications that will access these tables and the database admin does not want to relax the integrity of the relationships.
Any help is greatly appreciated. Details follow:
1. I have a RFQ entity bean that has a 1-N uni-direction relationship with RFQProduct entity bean.
a. RFQ primary key rfq_id.
b. RFQProduct compound keys - rfq_id_fk (foreign key from RFQ) and product_id. There is a foreign key constraint of NOT NULL set on rfq_id_fk.
2. I have a web page that takes in a rfq and 2 rfqproducts details. What are the steps for successfully creating a rfq entry and 2 rfqProduct entries?
3. Environment - I am using weblogic 8.1, xdoclet 1.1 and ant 1.5 SQL Server 2000.
4. In the RFQBean (Entity Bean)
public String ejbCreate(RFQVO newRFQ) throws CreateException
{
p("ejbCreate() - start");
this.setRfqId(newRFQ.getRfqId());
this.setRfqName(newRFQ.getRfqName());
this.setOrganizationName(newRFQ.getOrganizationName());
this.setRfqDate(newRFQ.getRfqDate());
this.setCreator(newRFQ.getCreator());
this.setSubmissionDate(newRFQ.getSubmissionDate());
this.setStatus(newRFQ.getStatus());
p("ejbCreate() - end");
// EJB 2.0 spec says return null for CMP ejbCreate methods.
return null;
}
public void ejbPostCreate(RFQVO newRFQ) throws CreateException
{
p("ejbPostCreate() - end");
}
/**
* Returns a collection of related eaisc.interfaces.RFQProductLocal
* @return a collection of related eaisc.interfaces.RFQProductLocal
*
* @ejb.interface-method
* view-type="local"
*
* @ejb.value-object
* aggregate="eaisc.interfaces.RFQProductVO"
* aggregate-name="RFQProduct"
* members="eaisc.interfaces.RFQProductLocal"
* members-name="RFQProduct"
* relation="external"
* type="Collection"
*
* @ejb.relation
* name="rfq-rfqproducts"
* role-name="rfq-has-many-rfqproducts"
* target-ejb="RFQProduct"
* target-multiple="no"
* target-role-name="rfqproduct-belongs-to-one-rfq"
*
* @weblogic.target-column-map
* foreign-key-column="rfq_id_fk"
*/
public abstract java.util.Collection getRfqProducts();
/**
* Sets a collection of related eaisc.interfaces.RFQProductLocal
*
* @param a collection of related eaisc.interfaces.RFQProductLocal
* @param cities the new CMR value
*
* @ejb.interface-method
* view-type="local"
*/
public abstract void setRfqProducts(java.util.Collection rfqProducts);
5. In RFQProductBean (Entity Bean)
/**
* The ejbCreate method.
*
* @ejb.create-method
*/
public eaisc.interfaces.RFQProductPK ejbCreate(RFQProductVO newRFQProduct) throws CreateException
{
p("ejbCreate() - start");
this.setProductId(newRFQProduct.getProductId());
this.setQuantity(newRFQProduct.getQuantity());
this.setProductName(newRFQProduct.getProductName());
p("ejbCreate() - end");
// EJB 2.0 spec says return null for CMP ejbCreate methods.
return null;
}
public void ejbPostCreate(RFQProductVO newRFQProduct) throws CreateException
{
p("ejbPostCreate() - start");
If I set the foreign key field as below, I get the following error:
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.
this.setRfqIdFk(newRFQProduct.getRfqIdFk());
If I comment the line below, I get the following error:
Foreign key constraint violation cannot be null from SQLServer & ejbcreate fails.
p("ejbPostCreate() - end");
}
In SessionFacade, I call the relevant entity bean methods as follows:
public void generateRFQ(eaisc.interfaces.RFQVO newRfqVO) throws ApplicationException
{
p("generateRFQ() - start");
RFQLocalHome rfqLocalHome = null;
RFQProductLocalHome rfqProductLocalHome = null;
p("SessionFacadeEJBObject bean lookup " + RFQFacadeHome.JNDI_NAME);
ServiceLocator serviceLocator = ServiceLocator.getInstance();
try
{
p("buildRFQProducts() - use ServiceLocator and locate the local home of RFQLocal Entity Bean");
rfqLocalHome = (RFQLocalHome) serviceLocator.locateEJBObjectLocalHome(RFQLocalHome.JNDI_NAME);
p("buildRFQProducts() - use ServiceLocator and locate the local home of RFQProductLocal Entity Bean");
rfqProductLocalHome = (RFQProductLocalHome) ServiceLocator.locateEJBObjectLocalHome
(RFQProductLocalHome.JNDI_NAME);
p("buildRFQProducts() - use ServiceLocator and locate the local home of RFQProductLocal Entity Bean - SUCCESS !!!");
}
catch (ServiceLocatorException e)
{
throw new ApplicationException(e);
}
p("generateRFQ() - creating new RFQ header record");
newRfqVO.setStatus("open");
RFQLocal rfqLocal = rfqLocalHome.create(newRfqVO);
p("generateRFQ() - creating new RFQ header record - SUCCESS !!!");
RFQProductVO[] rfqProductVOs = newRfqVO.getRFQProducts();
for (int i = 0; i < rfqProductVOs.length; i++)
{
p("buildRFQProducts() - Creating product[" + i + "] ...");
rfqProductVOs[i].setRfqIdFk(rfqLocal.getRfqId());
RFQProductLocal rfqProductLocal = rfqProductLocalHome.create(rfqProductVOs[i]);
p("buildRFQProducts() - Creating product[" + i + "] ...SUCCESS !!!");
rfqLocal.getRfqProducts().add(rfqProductLocal);
}
p("buildRFQProducts() - end");
}
Discussions
EJB programming & troubleshooting: CMR - ejbCreate foreign key constraint NOT NULL problem
-
CMR - ejbCreate foreign key constraint NOT NULL problem (8 messages)
- Posted by: sriram kannan
- Posted on: October 31 2003 01:31 EST
Threaded Messages (8)
- CMR - ejbCreate foreign key constraint NOT NULL problem by sergiu truta on October 31 2003 03:16 EST
- CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on October 31 2003 14:49 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by Mohit Sehgal on November 01 2003 01:31 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on November 02 2003 08:16 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on November 03 2003 10:59 EST
-
same problem by Luis RAMIREZ MONTEROSA on November 04 2003 07:06 EST
- Using ejbPostCreate by Mohan Samikkannu on November 05 2003 11:19 EST
-
same problem by Luis RAMIREZ MONTEROSA on November 04 2003 07:06 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on November 03 2003 10:59 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on November 02 2003 08:16 EST
-
CMR - ejbCreate foreign key constraint NOT NULL problem by Mohit Sehgal on November 01 2003 01:31 EST
- CMR - ejbCreate foreign key constraint NOT NULL problem by sriram kannan on October 31 2003 14:49 EST
- CMR - ejbCreate foreign key constraint NOT NULL problem by Greg C on September 16 2004 18:37 EDT
-
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: sergiu truta
- Posted on: October 31 2003 03:16 EST
- in response to sriram kannan
Hi,
I have several cases like this one you're facing. Let me tell you the solution that we have adopted.
Let's say that we have an entity A in a 1 to N relation with entity B.
In the ejbPostCreate of B I am giving a reference not to the primary key of A but to a Local interface of A. So it's like this:
ejbCreateB(..., ALocal alocal)
{...}
ejbPostCreateB(..., ALocal alocal)
{
setTA(alocal); <---here you are giving (as I've seen into your code) the pk but you should give a refference to the local interface of A
}
the setter used here in the ejbPostCreateB is the setter for the field in entity B that is refferenced as the <cmr-field-name> in your deployment descriptor(the one that implements the relation).
The only problem with this is that the ForeignKey field in table B can't have the restriction not null and I will tell you why I believe it is so(anyone please correct me if I am wrong because I am also a newbie in CMP). I think that first gets created the entity B and inserted into table B and only after this gets created the relation. I think this is the reason why you can set a relation only in ejbPostCreate.
Hope this helps you ;)).
Sergiu -
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: sriram kannan
- Posted on: October 31 2003 14:49 EST
- in response to sergiu truta
Thanks for your prompt response. I have tried the scenario that you have suggested. Removing the NOT NULL constraint, I know, will resolve my problem too as explained & implemented correctly by you. However, I do not have the luxury of relaxing the NOT NULL constraint as specified in your response as well as in my earlier email.
1. What exactly happens behind the scene, when you call setTA(alocal) method? Does the container update the foreign key (behind the scene) on the newly inserted record?
2. Even with your suggestion, at then end of ejbCreate() method, the database record is still written to the database for Entity B, which fails due to null foreign key - (set only in ejbPostCreate). Is there anyway to let container know to postpone all database updates after the ejbPostCreate()? I read a weblogic setting to delay the insert after ejbPostCreate but that did not solve the problem either. Am I missing something? This problem situation seems to me to be a fairly common occurence in database design, and I am curious to find out how you guys have figured this out? Pls help!!!!
> Hi,
>
> I have several cases like this one you're facing. Let me tell you the solution that we have adopted.
> Let's say that we have an entity A in a 1 to N relation with entity B.
> In the ejbPostCreate of B I am giving a reference not to the primary key of A but to a Local interface of A. So it's like this:
>
> ejbCreateB(..., ALocal alocal)
> {...}
> ejbPostCreateB(..., ALocal alocal)
> {
> setTA(alocal); <---here you are giving (as I've seen into your code) the pk but you should give a refference to the local interface of A
> }
> the setter used here in the ejbPostCreateB is the setter for the field in entity B that is refferenced as the <cmr-field-name> in your deployment descriptor(the one that implements the relation).
>
> The only problem with this is that the ForeignKey field in table B can't have the restriction not null and I will tell you why I believe it is so(anyone please correct me if I am wrong because I am also a newbie in CMP). I think that first gets created the entity B and inserted into table B and only after this gets created the relation. I think this is the reason why you can set a relation only in ejbPostCreate.
> Hope this helps you ;)).
> Sergiu -
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: Mohit Sehgal
- Posted on: November 01 2003 01:31 EST
- in response to sriram kannan
To answer your first question, setTA(alocal)is doing exactly what you are saying. It will set the appropriate foreign key in entity B. Relationship by spec can only be set in ejbPostCreate. Secondly as the previous post explained, do set CMR field for the relationship and do NOT define ur foreign keys as CMP fields.
I am NOT sure why delay-database-insert-until set to ejbPostCreate is not working for you (somehow ur insert for entity B is getting to the database before u intend to). Logically ur insert for entity B should not be fired, so that means it is created in memory and then updated in memory. After ejbPostCreate, when insert statement is flushed to the database, the foreign key is already set (in ejbPostCreate).
I can think of 2 options:
You can try the delay-database-insert-until being set to 'commit'. This performs a bulk insert when the transaction commits. So basically before committing ur transaction, ur foreign key should have been set (in ejbPostCreate).
Another very useful option is telling the database team to turn on 'checking database constraints at the end of transaction'. Atleast this feature in provided in oracle by name of 'deferred constraints'. Here the constraints will be checked at the end of transaction and not during running of each SQL statement in the transaction. This way DB team does not have to remove the constraints and also your problem will be solved.
I am speaking mainly of weblogic app server above.
Mohit -
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: sriram kannan
- Posted on: November 02 2003 20:16 EST
- in response to Mohit Sehgal
Let me try your options and let you know. In the meantime...
1. Could you give me an example on where and how the "delay-database-insert-until" option - maybe a listing of the cmp descriptor? I am not using the tags properly....it looks like!!!
2. Currently, (to my knowledge) there is no way to generate the "delay..." tags in the XML descriptors using Xdoclet. I have to manually edit my file after ejbdoclet task has generated the descriptors. How did you include the tag in ...cmp descripor - manual editing? -
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: sriram kannan
- Posted on: November 03 2003 22:59 EST
- in response to sriram kannan
I got the whole thing to work!!!!!.
There was a problem in the way that I had defined my 1-N CMR relationship using xdoclet tags. The ejb-jar.xml deployment descriptor was not generated as expected.
By default Weblogic 8.x uses delay-on-insert after ejbPostCreate and setting the RFQLocal in the ejbPostCreate as correctly suggested by you guys worked without any constraint problems.
Thanks for your help guys.... -
same problem[ Go to top ]
- Posted by: Luis RAMIREZ MONTEROSA
- Posted on: November 04 2003 19:06 EST
- in response to sriram kannan
hey i'm kind of having the same trouble.. but i'm working with Oracle9iAS 9.0.3.0.0 i'm sorry but i'm a rockie and i do not hava the idea wheres that tag to delay after post create would you tell me please?? -
Using ejbPostCreate[ Go to top ]
- Posted by: Mohan Samikkannu
- Posted on: November 05 2003 23:19 EST
- in response to Luis RAMIREZ MONTEROSA
Hi,
Iam also getting the same problem.can u please help me in this regard.Iam using oracle9ias.how to use "delay..." tags in OC4J.can any one send me some sample.
Thanks in advance
Samy -
CMR - ejbCreate foreign key constraint NOT NULL problem[ Go to top ]
- Posted by: Greg C
- Posted on: September 16 2004 18:37 EDT
- in response to sriram kannan
Hi,
I am using CMR/CMP and things are working fine with "delay updates to commit" enabled. However we have a reason for wanting to DISABLE this and I am getting the same issue as mentioned below.
My child object ejbCreate currently is:
public void ejbPostCreate(String nmCreatedBy, Timestamp dtCreatedOn)
throws CreateException {
}