Sunday, October 7, 2007

JEE isn't just about ORM

I had a conversation with a friend about JEE and how they thought it can be overkill. I should preface by saying I do believe there are situations where JEE is overkill, which I won't go into. His argument is if you don't need to access a database with an ORM then you don't need JEE.

I strongly disagree with this, mostly because I do this all the time. I love Hibernate and EJB3 entity beans, but it doesn't work for all schemas. If you have a highly normalized relational schema where you can take advantage of 2nd-level caching then entity beans is a blessing. But if you are recording stats and doing more OLAP stuff then you may want to stick with straight JDBC.

However, JEE works great with JDBC also. In fact most deployments I've done, including one I'm currently responsible for, use both. Take the following example


public @Stateless class PersonStatsBean implements PersonStats {

@Resource(mappedName="java:/LoginStatsDS")
DataSource loginStats;

@PersistantContent
EntityManager em;


public void recordLogin(int person_id) throws JDBCException
{
Person person = (Person)em.find(Person.class,person_id);
Connection con = null;
try {
con = loginStats.getConnection();
PreparedStatement stmt = con.prepareStatement("insert into login_stats(person_id)
values (?)");
stmt.setParameter(person.getId());
stmt.executeUpdate();
con.close();
}


}




In this example I am saving a row that keeps track of every time a user logs into my system. I have an EJB3 entity called Person that is managed by the entity manager. But I also inject a a regular JDBC data-source into my bean that keeps track of login stats. The login_stats table may be a million rows long and denormalized for reporting efficiency so it really doesn't map well to an ORM. The entity manager and the data source could be pointing to the same or different databases, I don't care.

The cool thing is even though I'm using entity beans and JDBC, the application server makes sure they are both enlisted in the same XA transaction. So even though I ask the container for a regular JDBC data-source by the time I get it an XA transaction has already started and is being managed. I could save/update some EB3 entities and execute some JDBC statements and they will be fully ACID compliant.

So yes Matilda, you can have your EJB3 and JDBC too. By using JEE we are not tying ourselves to a predetermined set of abstractions. If I want an ORM, I get that... If I want to do straight JDBC, I get that also. And if I want to do both, I can have that too AND they all play by the same ACID rules.


P.S. You notice that I have to have this function throw a JDBCException. I wish JDBC would follow the path of EJB3 persistence and make their Exception hierarchy extend RuntimeException rather than Exception. But thats just a picky observation, not a framework killer

No comments: