I've been writing a bean-managed entity bean the last couple days and have tweaked it so that the performance is as good as or better than a similar CMP bean under Orion. However, I still have this nagging feeling I'm doing things wrong...
I was able to get the bean to be fast by keeping a connection from the pool for each bean in context (ouch!). During a test script, I opened 50 beans and suddenly had 50 open connections. I am also saving a prepared statement to achieve quick response time. Also, I used a "cachedKey" with the idea that there is no need to have a database lookup if the entity is already in context.
So two questions:
1) Am I on the right track? Is there a defined way to write BMP entity beans for optimal performance? I found several examples on the web (including on javasoft) that use sub-optimal techniques.
2) Should I even use entity beans at all? I've heard from some people that they aren't ready for prime time, and I have to agree in some aspects: If I wanted to get the title for rows 1 to 50, I would have to create 50 entity beans and make 50 single-row queries. Why not just make a session bean that can handle both single- and multi-row queries? During my test script that did getTitle() for 50 BMP entities, the first time I ran the script it was pitifully slow, but then obviously after that it was screaming fast since no database calls were made.
To recap: is there a defined way to do BMP entity beans (ie: keep a connection for each entity open, or only open the connection when I need to? If I do the latter, then I cant save a prepared statement and then performance slows down quite a bit). Please offer any suggestions you might have, and maybe we can create a pattern out of this. =)
I typically use BMP instead of CMP because it gives me more control over tuning my application. Applications that require database access (most of them do) typically spend 60% to 90% of their time talking to the database. Therefor the largest gains in tuning an application are often in tuning the application's interface to the database.
Also, I tend to use a more course grained approach to design, not having a 1-to-1 mapping of entity beans to tables in the database. This is because an optimal entity (database) design will diverge from an optimal object design for large systems.
As far as caching connections, this wont scale well, as you have already discovered. There are two things that will help performance with regard to database connections.
1. Make sure there are a sufficient number of connections in the connection pool.
2. Cache the reference to the Datasource (not the connection). This will eliminate the lookup of the Datasource in the JNDI server.
Saving the prepared statement won't work well either because it is not thread safe. You will end up with database cursor errors, especially when retrieving more than one row, or when attempting to retrieve a row when another bean has written/commited since the cursor (prepared statement) was opened.
Using a cached key might be dangerous depending on the type of bean. If the bean is accessing a shared database (database is used by other external application(s)), You could end up with some strange behavior or exceptions if the record in the database is deleted from underneith you.
As for the last question, should entity beans be used, it depends on what the bean is needed to do. One valuable use of entity beans is for objects that will be cached and used by multiple sessions (users) simultaneously. This allows you to adopt a caching algorithm (supported by your container) without having to write the caching mechanism yourself. This can greatly enhance performance. For short-lived objects that will not benefit from a cache, session beans might be a better fit. This shouldn't be viewed as a hard rule but might be a good place to start when deciding between entity beans and session beans. Certainly session beans are generally faster and have less overhead.
Sorry to be so long-winded. Hope this helps.
I have a different take on this issue. If the development time for a product is very small and if the objects have a near 1-1 mapping to the underlying table structure, then it is easier and time saving to do everything with CMP. But if the queries are across multiple tables and if CMP makes the performance slow then BMP seems better. BMP does give better control and BMP is more easily ported between App Servers.
How are caching the initial context in your BMP? I agree that doing an InitialContext is expensive. Wld appreciate any good examples here and anywhere else on the net.
We're currently experiencing slow response during lookup() of datasource as we are not caching the datasource.
Do you have any sample code for doing the caching?
If so, would appreciate if you could post it here or email it to me at vincentwahkit at crosswinds dot net
Thanks in advance.
but what about now?ejb3,jpa,jboss4.x-hibernate...
I am still prefer bmp,nut I still want to learn your viewpoint.