database-persistence in jboss
aqil Oct 10, 2001 2:19 AMi found the following notes in the notes.txt of the BMP example of jboss at
http://www.squinky.org/jboss/
i need comments on the this text
================================
This error:
[JAWS] Initializing JAWS plugin for CDBean
[Container factory] java.lang.NoSuchFieldException: CASE_INSENSITIVE_ORDER
comes from not specifying the primary key field for CMP beans in the ejb-jar
file. You need <prim-key>...</prim-key>
This error
[Container factory] org.jboss.ejb.DeploymentException: Could not find matching
method for public abstract java.lang.String somepackage.getSomeField()
throws java.rmi.RemoteException, Cause:java.lang.NoSuchMethodException:
getSomeField
Occurs because the JAWS plugin used by jBoss expects the remote interface to
have all its methods specified as `abstract'. This isn't required in general,
but it doesn't hurt to do it anyway.
jBoss does not like to have a database table change its number of columns; if
you add a CMP field to a class after it has been deployed, you can expect
problems. Merely restarting the server won't be enough: you may have to
re-install it. If you are running a number of projects on the same server this
is going to be very inconvient.
The method `public Collection findAll()' if specified in a home
interface will be expanded automatically to a method call that
really does find all the records. It returns a Collection object.
Oddities
I come from a tradition in which the `primary key' of a table should be
unique, that is, there should only be one row with that primary key. Indeed,
the definition for `findByPrimaryKey()' of the EJBHome interface has it
returning a single object, not a collection. jBoss seems to allow primary
fields to be non-unique; then findByPrimaryKey() actually finds the first
matching row!
Although hot deployment works well, if an error occurs during deployment it is
possible that you will need to restart the jBoss server. This is particularly
noticeable with `NoClassDefFound' errors; these arise if you package a Bean
without the supporting classes it needs.
If you throw an exception out of a Bean, the jBoss server interprets this as an
error condition, even if it was intentional. In other words, you should not
throws exceptions to indicate unwanted, but normal, circumstances.
A particular nasty is using findByPrimaryKey to check whether an entry is
already in the database; if it is not, then you will get an exception dump on
the console. Even if you application traps the exception (and it will), you
will still get the dump. This is very disconcerting and slows things down even
more.
In this piece of code:
string id = "something";
SomeClass someObject = home.findByPrimaryKey(id);
no exception is thrown if the primary key is not found. An object of class
SomeClass is instantiated, and execution continues as normal. An exception is
only thrown when the program tries to do something to this object. So:
String dummy = someObject.getSomeField();
will not throw an RMI exception. I understand that this behaviour is allowed by
the specification, and is for reasons of efficiency. However, if you really
need to check that an object exists before you do anything else, then finder
methods should be followed by access methods to force a check.
jBoss CMP does field updating by recording the existing field values, deleting
the row of the database, then writing the new row with the new values. This
means that if you create an object and set its ten (say) attributes, this will
translate into at least 21 whole-row operations!
The jBoss database is persistent, in that its data is retained even when the
server is stopped. However, its persistence is managed in an odd way, by
writing out a script of SQL commands that will re-build the database. This file
cann become extremely large. It's not obvious that this is a good way to do
this.
If your database tables are large (i.e., bigger than toy programs) you will
find that an interpreting JVM does not offer sufficient speed to be useful.
That's not a criticism of jBoss; it's just that it takes a lot of operations to
search a table, and the quicker those operation are, the better. Performance
that is just about adequate can be obtained using the `Hotspot' version of the
JDK, but it's probably worth investigating proprietary JIT compilers for real
work. I had some difficulty getting the Hotspot JVM working on my Linux
development system, and in the end had to recompile the pthread library (ugh!)