ejbPostCreate: bean not saved

The application that I'm debugging is inserting a record into a table (say Table A) and inserted some related data into a related table (say table B). Table A is implemented with a CMP entity bean. Now the ejbPostCreate method is written to write to table B by calling some utility class(does not use entity bea). This technique is a simple one that I've found examples for on the web. However, in our application when table B is being inserted into, I'm getting a Oracle database error saying that that the FK cannot be found. This FK is the PK in table A. So what this means to me is that in the ejbPostCreate method, the insert is not committed and was inserted in a different database session, if it was inserted at all. I should point out here that the CMP Entity does work for the overloaded ebjCreate/ejbPostCreate methods that insert a Table A record with no related tables. This behavior contradicts all of the promised behavior that I've found on the Web. Does anybody have any insight into what might resolve this issue(xml configuration perhaps)?

How did the utility class insert data? using JDBC, ORM (Hibernate, Toplink,...) What is the transaction attribute on ejbPostCreate()? Make sure it is running under the same transaction as it is in ejbCreate().

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Mar 26, 2007 12:23:00

0

Thanks Vu for responding. The table B record is being inserted using jdbc. The CMP Entity bean is configured to use the same jdbcPool in Weblogic as that used by the table B insert. I'm not sure where to look for the transaction attribute in the ejbPostCreate. Can you tell me where?

That's a very good question, Vu. This application was ported from weblogic 5.1 to 7.0. The weblogic-ejb-jar.xml says to use the weblogic 5.1.0 persistence type - I didn't change that going to weblogic 7.0. The ejb-jar.xml file refers to the ejb 1.1 DTD but I don't think that effects which ejb version is used. The ejb was built using ANT and the weblogic.ejbc compiler from the weblogic 7.0 environment so I assume that the build/run ejb versions are in sync.

Thanks Nitesh. The code used to work in the weblogic 5.1 environment. I think you're right that the ejbCreate and ejbPostCreate should be within the same transaction. I would think that the table A and table B should also use the same jdbc connnection object. The ejb is configured to use the same weblogic jdbc pool as the utility code that inserts table B. Anyway, how do I ensure that these inserts are done within the same transaction.

Hey Mark, can you post the DD as well as the code for ejbPostCreate. Essentially, if you are looking up a weblogic datasource to create database connections, it should be able to see the database inserts made after ejbCreate(). But as you said, that it used to work with weblogic 5.0, then it must not be a problem with the code. Must be something related to the DDs. May be if i can see the DD, i will be able to help. But, dont really depend on me for this

vu lee
Ranch Hand

Joined: Apr 19, 2005
Posts: 192

posted Mar 28, 2007 11:32:00

0

Correct me if i am wrong. But the container always calls the ejbCreate() and ejbPostCreate() methods in the same transaction context. As far as i remember, that is what the specs(2.1) mention.

In this case, the author used utility class which in turn used JDBC to insert related data. Even ejbCreate() and ejbPostCreate() were running under the same transaction, if the utility class used different transaction to insert data, it would run in different transaction. [ March 28, 2007: Message edited by: vu lee ]

In this case, the author used utility class which in turn used JDBC to insert related data. Even ejbCreate() and ejbPostCreate() were running under the same transaction, if the utility class used different transaction to insert data, it would run in different transaction.

How does this client utility get hold of a different transaction? I thought it was getting the connection from the weblogic datasource, this would mandate that the statements executed on the connection will be in the same tx context as ejbPostCreate. Yeah, if the author has used DriverManager instead of datasource to create connections, then i think, it would have never worked, but for a case where the tx is committed even before calling ejbPostCreate which i don't think happens anytime.

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Mar 28, 2007 15:15:00

0

Yes the utility looks up the datasource from weblogic whose jdbcpool is the same as that configured for the ejb. Am I to understand that it doesn't matter if the ejb and the utility are using different Connection objects? As long as the inserts are done within the same transaction then that equates to the same database session?

vu lee
Ranch Hand

Joined: Apr 19, 2005
Posts: 192

posted Mar 28, 2007 16:12:00

0

I thought it was getting the connection from the weblogic datasource, this would mandate that the statements executed on the connection will be in the same tx context as ejbPostCreate.

Getting connection from the datasource does not guarantee ejbcreate() and ejbpostcreate() are running under the same transaction. To demonstrate my point, for example, suppose the utility client is a BMP, which gets connection from the same connection pool, then these two methods would run under different transactions since BMP would run under different transanction. (My understanding is that BMP does not accept inbound transaction.)

Assume these methods are working correctly. If these two methods were running under the same transaction, ejbpostcreate() would have seen whatever intentionally written to the database by ejbCreate(). Since ejbpostcreate() did not see whatever written to database by ejbCreate() in the transaction context, these two methods could have ran under different transactions. [ March 28, 2007: Message edited by: vu lee ]

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Mar 28, 2007 17:04:00

0

Yes I suspected that the utility and the ejb were using a different Connection objects(session). How would I ensure that they're using the same Connection object? Can I somehow get the Connection object from the CMP and pass it to the utility?

Originally posted by Mark Savory: Yes I suspected that the utility and the ejb were using a different Connection objects(session). How would I ensure that they're using the same Connection object? Can I somehow get the Connection object from the CMP and pass it to the utility?

See, as far as i know, if you use the datasource under a transactional method in a CMP, to create connections, the newly created connection should have the same transaction context as the method. So, i do not see a reason to look for the same connection as the CMP uses. As a matter of fact, you can not get the connection that CMP uses. Moreover, if this was working with weblogic 5 then i do not see a problem with the code that it should not work with weblogic 7.

Getting connection from the datasource does not guarantee ejbcreate() and ejbpostcreate() are running under the same transaction. To demonstrate my point, for example, suppose the utility client is a BMP, which gets connection from the same connection pool, then these two methods would run under different transactions since BMP would run under different transanction. (My understanding is that BMP does not accept inbound transaction.)

A few clarifications, Calling a BMP from a CMP method suspends the transaction associated with the CMP, as a matter of fact, on calling any bussiness method on a BMP, the existing transaction(if any) gets suspended. There is a difference between calling a BMP business method and looking up a datasource in the CMP method using a utility class. In your example, it does not mean that ejbCreate() and ejbPostCreate() are running on a different transaction. They are always in the same transaction. However, the business method of the BMP is running in a different transaction. Since, ejb does not allow nested transactions, so the transaction of ejbPostCreate() is suspended till the transaction started by BMP ends.

Assume these methods are working correctly. If these two methods were running under the same transaction, ejbpostcreate() would have seen whatever intentionally written to the database by ejbCreate(). Since ejbpostcreate() did not see whatever written to database by ejbCreate() in the transaction context, these two methods could have ran under different transactions.

I agree with you, that is why i said that there may be a problem with the DDs or in the porting but not in the code for sure. [ March 29, 2007: Message edited by: Nitesh Kant ]

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Mar 29, 2007 13:42:00

0

I'm not sure what the DD is. Is that the weblogic-ejb-jar.xml file or the ejb-jar.xml file?

Originally posted by Mark Savory: I tried setting <delay-updates-until-end-of-tx> to false already but it didn't make a noticable change in behavior.

One last try, can you set the isolation level on the connection used in your utility class to java.sql.Connection.TRANSACTION_READ_UNCOMMITTED But, now i really doubt whether this is a transaction issue.

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Apr 06, 2007 10:30:00

0

I'm happy to try different things but I'm wondering about this one. The transaction level TRANSACTION_READ_UNCOMMITTED is supposed to allow other transactions to read uncommited data that was modified from another tranaction. One, why would you ever want to do that? Two, what does this have to do with my stated problem?

Originally posted by Mark Savory: I'm happy to try different things but I'm wondering about this one. The transaction level TRANSACTION_READ_UNCOMMITTED is supposed to allow other transactions to read uncommited data that was modified from another tranaction. One, why would you ever want to do that? Two, what does this have to do with my stated problem?

Well, if at all your utility and entity bean are running in different transactions, then essentially, the transaction of entity bean would not be committed before ejbPostCreate() completes, so setting this isolation level on your JDBC connection will see the uncommitted data of the entity bean i.e. the rows created by the entity bean. Specifically, this would make sure that these two methods are running under different transactions. Again, it is just something that i would have tried, so just suggested, of course its entirely upto you to consider it or not. [ April 08, 2007: Message edited by: Nitesh Kant ]

Mark Savory
Ranch Hand

Joined: Feb 08, 2001
Posts: 122

posted Apr 09, 2007 08:48:00

0

Ok I see how that would show that there are two transactions. That's a good idea.

Update: I think I discovered what the problem is. In Weblogic 7.0, I should be using TxtDataSource because that honors global transactions. TxtDataSource was defined in Weblogic 5.1 but when the applications was ported to 7.0, only a plain DataSource was configured - oops.