I realize that this topic has been covered before and I also realize that file I/O is something that should not be done inside of an EJB container. However, I also realize that things like Hibernate do it all the time.
We are looking to implement our own form of ORM tools and we need to figure out how to read the mapping files from the filesystem inside of the EJB container. I figure if Hibernate can do it, then so can we. However, we can not figure out how to do it. Specifically, we are trying to access files inside the EJB container using JBoss and Sun Java system application server. We are not having any success.
I understand the reasons for not doing file I/O in session and message driven beans, however, are there any problems associated with the method Hibernate uses to access files?
Okay, I can now see many people asking, if I relate all this to Hibernate so much, why not just use Hibernate? Speed and performance is one reason and the other reason is that Hibernate is simply a well known example of an application that is already doing what I want to do inside the EJB container. And no, I have not had time to wade through all the Hibernate source code to look for how it does it. It is on my todo list.
However, I also realize that things like Hibernate do it all the time
Strictly, Hibernate only every does file input. It doesn't do anything unusual the Configuration class just uses a SAXReader to parse the XML mapping files and cache them in the SessionFactory. Its not the only componentent of an EJB-based application which does this sort of thing: logging for example, can use configuration files.
There is nothing to stop you doing this kind of File I/O in an EJB, other than the rule which say you can't. Containers won't stop you. The usual reasons given why its a bad idea are:
Accessing the File System breaks the write one, run anywhere goal, since File Systems differ in their implementation.
Its a security hole. All other resources are managed by the container, so security is also managed. File acces is not.
File access is not transactional.
File access is not going to work in a cluster
As far as Hibernate is concerned, the only issue it might have to worry about is security. The mapping files are read in as a resource, kind of like any class file would be. So its the classloader which does the actual file access. And since its only input, it doesn't matter that its not transactional.
For a clustered environment, its fine to do this sort of parsing of an XML resource from an EJB. Once its done, the sensible thing to do is cache the XML and bind it in JNDI. Now any other ejb can safely look it up as they would any other JNDI resource. And since its cached, it make even more sense to do this before any EJB's are deployed. Since you mention JBoss, you might consider the MBean approach Hibernate recommend (have a hunt around their docs).
Speed and performance is one reason
You are aware that Hibernate claims to be the most performant ORM around?
This is a issue with file systems and EJBs. When I needed to read file from file system (for castor xml mapper) I put these mapping files to root of EJBs jar file (or some subdirectory) abd read it using getResourceAsStream. For example I put "PdfBean.xml" file to EJBs jar to "/mappings/PdfBean.xml" and then read it in EJB: getClass().getClassLoader().getResourceAsStream("mappings/PdfBean.xml"). I used it in Jboss app server.
Other solution is to load this file via some connector.
All the file IO that I need to do is read, or input, only. It is simply to read some configuration or mapping files. So I will try the GetResourceAsStream method. Thanks.
As for hibernate, yeah, I am aware that it is suppose to be fast, however, without actual real benchmarks to back that claim up, there is not much hope I have of convincing my bosses to go with it instead of rolling our own. By benchmarks, I need info on how many transactions per minute (preferably in the 1,000+/min area) and how large the objects are that are being saved. We need to be able to save 4,000 objects to a database through multiple transactions every 5 minutes. Each object is actually an object graph of up to 600 objects. So in reality that could be 2,400,000 objects every 5 minutes. (although, broken down at this level, these are very small objects)