until recently I've been coding business logic
in PL/SQL and calling my stored procedures from plain
standalone Java apps through JDBC. Now it is desirable
to make the project database independent.
I am considering using CMP Entity EJBeans and not
writing any SQL code (only declarative stuff in
deployment descriptors). For lack of better ideas,
I imagine distinct database tables as distinct types
of Entity Beans, while distinct rows in the same table
look to me like distinct instances of the same Entity Bean.
So far everything is fine and indeed I am able to create
and populate tables on an arbitrary database (using my
old schema!) without writing a single line of SQL.
What I do not see immediately, is what is the analogue
of table joins in this approach? In general, do you
think Entity Beans should be normalized the way
database tables are, or should my existing highly
normalized schema be abandoned?
Thanks for any comments or links or references.
I would say you have two options: Bean Managed Persistence, or fool the EntityBeans into thinking there is a single table by creating views and triggers in you DB.
The first will definitely work regardless of what DB you are on but might be a bit slower than the second if the EJB server needs to cross a network to get to the DB server.
As for the second, it may require DB vendor specific procedures. Thus, you either won't be able to use a different DB, or you will have to re-write those procedures for another vendor.
Overall, both methods require doing a bit of code writting (SQL vs , the difference being, how portable/fast do you want your app.
DOH! That last apragraph should read:
Overall, both methods require doing a bit of code writting (SQL in BMP vs whatever in the DB), the difference being, how portable/fast do you want your app.
And apparently I can't spell either...
Out of curiosity, what are the business entities you are trying to model, and what sort of business entity is represented by a table join?
In my (rather limited) experience, I have been reasonably satisfied modeling my business entities with CMP entity beans, container managed relationships, and finder methods (I'm using EJB2.0 beans).
Is it just that you have all the components of a single business entity stored in different tables with a single PK? If you want to provide a seamless view of such an entity, you're definitely looking at BMP or special tricks with views and triggers. CMP wasn't designed to map onto arbitrary schemas (that's what BMP is for); it's designed to allow you to stop worrying about the persistance layer.
If you really want CMP and you really want to keep your schema, you could just model all the pieces as different beans. Since you probably have all your entities hidden behind session beans, you could at least provide a seamless view to clients. This might require quite a few extra database hits, though.
Thanks for comments.
To clarify, I do not care at all about preserving
the schema or best possible performance. What's
important for me is database independence.
However, being database-centric, it is difficult for
me to imagine a non-normal database.
A simplified version of what I am doing is like this.
The three tables are
A business entity that I would get by joining is
a pile of all shipping labels to put
on the boxes: (Customer.NameAddress,Product.Description)
A naive approach is to have Customer, Product, and Order
CMP beans, and sorta join them manually by juggling
enumerations returned by their respective finders.
But what's the correct approach?
Ahhh... Well since you asked for the "correct" approach, you should first consider how you approach the issue.
You are writing code for a business process, thus the starting point of your evaluation should be in the middle tier and work outwards from there.
So your first question will then be: "What Entity do I need for my business process?"
The answer, using your example, would be a Label Entity containing the Customer Name, Customer Address, and the Product Description.
If THAT is what you need for your business logic, THAT is what the EntityBean should be.
So now you have that down, move outwards from there to the data layer... whoops, it doesn't map directly to a table.
The only option, if you want to be DB independent, is to use BMP, and then perhaps talk with your DBA :)
I guess the big point here is to base your EntityBeans on the way your business process needs them, not the way they sit in the DB.
Thanks for a fast reply.
> whoops, it doesn't map directly to a table.
But objects almost never do! Objects are denormalized, and
tables are, well, normalized. So how is CMP ever going
to be usefull?
I was under an impression that one should always use CMP unless she really really knows what she is doing. I did not think that a trivial example such as above would qualify for that.
Should the correct recipe be "you can only use CMP Beans if you just have one table in your database (or a bunch of entirely unrelated tables), otherwise use BMP Beans, one class per each table join you may ever need"? That would be very different.
I understand what you mean, but again, your first priority should be modeling Business Entities.
Using your example, Customer and Product Entities would definitely use CMP. Order may use CMP depending on what your business needs an Order Entity to contain. Label would definitely not map to a table, so then you are left with BMP.
I grant you, Label may not be a good example of a Business Entity, but ignoring that, you possibly have 75% of the above beans using CMP.
I am presently in the modeling phase for designing a large EJB system, and I can tell you that about 75% of my Entities will use CMP.
Overall I couldn't care less about writing SQL in every Entity... the idea here is to not deal with it in the SessionBean. The benefits gained are based in the fact that the Entity is simply encapsulation of data that can fill itself from the database, validate data input, and then save itself back to the database, thus the business logic in your SessionBeans are blissfully unaware of the how or why of it.
Hope that helped :)
There was talk about using BMP or maybe using views etc.
If i model my Entity Beans on DB-VIEWS how can i do the inserts ?
Is it a good approach to use Toplink or Cocobase in this scenario where I need joins of tables.?I guess these 3rd part vendors create EntityBeans depending on table-joins and toplink/cocobase can also be integrated with weblogic containers.
Any help in this matter is greatly appreciated.
The problem you are detailing only exists in the EJB1.1 spec where each entity bean can only be mapped to one table. The new EJB 2.0 spec supports multi-table Entity beans. For your case, a view that does the join for you would be the best solution (your beans only need to read the data, not update it).
For the future, I would recommend getting an app server that supports the EJB 2.0 spec. But in this case you can use a view to get the data you need for printing out your labels. Most modern RDBMSes support views. And it requires just a small amount of extra work for your DBA. :)
I would consider the question yet again. A business entity is a persistent thing, something you'd like to store in the database with a unique identity. To me, a packing label does not fit that description, but I may be wrong.
This is a pretty classic problem. For a given object (order, order line items) fetch some related information (product and customer information) and display it to the user (print on a label). The label is a data object, it is transient and not persistent.
I would think a good design for this would be to have a method to get mailing label which returns the label data object for a given order.
I would think a good design for this would be
> to have a method to get mailing label [...]
I absolutely agree, so that's the question -- could this method work in any way other than by explicitly calling
SELECT statement against the underlying database?
The point here is to try to work with java-world objects ONLY and not with database-world SQL strings you push into JDBC.