Trails gotchas

Look people, this is a Wiki

The information on the site is maintained by the community, especially some pages like this more than others. Committers take no (full) responsibility of information on this page being up-to-date.

Here are a few of the most important things to check when trails are behaving strangely:

1)

Sometimes, when you make changes to a class, you may need to drop the related tables in the database. If you use mysql on linux, you can use phpmyadminwhich is written in PHP and commonly uses apache. If you by ay chance are running a debian linuxbased distribution such as ubuntu which is ridiculously simple to install, all you have to do from the command line is (as root) to run "apt-get install apache2 phpmyadmin" and wait a little bit and then login at http://localhost/phpmyadmin as your database adminstrator user.

When you make changes to classes which are related to other classes, as Recipe and Ingredient are in Chris Nelsons second trails article, you should drop both tables. Also watch out for hibernate makinging lookup tables, which will have names like one or more of the related tables.

If possible, just drop the entire database between each change, but in mysql's case, you must recreate an empty database with the same name as your project, before starting or deploying to the tomcat server again.

If you are lazy like me, just let hibernate drop the tables for you. If you can't do it all the time, you can alternate between:
hibernate.hbm2ddl.auto=update
and
hibernate.hbm2ddl.auto=create-drop

Modifying hibernate.properties is no more difficult than pulling out phpmyadmin every time you need to do something.

2)

If you by some chance haven't got a doctors degree in hibernate and maybe even checked trails out because of its seeming ease of RAD, you might well hit a small but efficient brick wall at about your third hour in. This brick wall will mostly consist of JSR-220 implications that, when you finally understand them will make you it yourself repeatedly in the head with anything handy.

To avoid injury, check out the following rather terse and to the point examples which are very much related to what you will have to consider in making trails work for you:

    a) Cauchu overview of Hibernate annotations, arguments and usage
    b) Informit's reasonable ManyToOne, ManyToMany, etc. example classes with enough comments to go

3)

Avoid using (cascade=CascadeType.ALL) on more than one relationship, if you have more than one class with a relationship to another class.
Otherwise you might get strange, nay, outrageous error messages (althoug formally quite correct) from hibernate, complaining that another object with the same name already exists somwhere.

4)

Do not by any means skip over the provided examples!!!!!!!!!!!!!!!!!  If you do not use subversion, which is demonically simple to use from a user point of view, at least check out the example sources at the repository!, especially the so called "simple" example which has all you daily vitamins and more.

5)

Never, ever give in to the temptaiton of using java.sql.Date when using Date properties in your classes. OK, it's first in the list and it _is_ a database at the bottom, but if you do, your dates will never be saved, for unclear reasons. Use instead java.util.Date and all will be well.

6)

If you ever get an exception in the tomcat logs (i.e. catalina.out) that looks like this "org.hibernate.AnnotationException: CampaignQuestion collection not yet supported: CampaigncampaignQuestion" you have tried to use a POJO (Plain Old Java Object) relation as if it were a Collection.  In plain english, this means that you previously had a Set of somethings, maybe with a relation like @OneToMany, then you thought; "Oh, wait. I should have only one of something here", and changes the property, getters, setters and all from a Set<something> to just a plain something.

Naturally you forget to change your annotations, which still read (perhaps);

@OneToMany(cascade=CascadeType.ALL)
@Collection(child=true)

And it's not a collection anymore, now, is it? Natch!
This has of course never happened to me personally, but there's this guy I heard about who ...

7)

If you are using a recent version of trails and/or checked out something recent from subversion - and get weird and unhonorable insinuations from hibernate concerning properties which worked perfectly well, thank you very much, just a day or so ago - try do downgrade to an older database driver.

Specifically, the mysql connector was upgraded to a spanking new version at one point, which vehemently declined to save Date's in the format in which hibernate would've liked to. It took a couple of days to sort that one out (which in retrospect seems rather an easy one, I'll admit).

Executive brief: When hibernate lows, change jdbc-drivers until it is satisfied  (In the ./lib directory

UPDATE: OK. here's da dilly; If you're using MySQL 4.1, you must use the 3.0 hibernate driver, if you use MySQL 5.x, you must (at least) use the 3.1 hibernate driver. So there.

8)

At some point you will have to set some extra properties on a relationship class. You might have a class in trails which is a Forum and which has a relation to a Set of Members. When a Member is created, you want to set some nice property on it, which only exists in the Forum, say a Set of Message objects, perchance?

So, you dilligently search hibernate docs (OK, I asked Chris , and come to the conclusion that if you add a method to you Forum class with the magic name "addMember(Member m)"  this will automagically be called whenever a new member object is created in trails.

What is not readily apparent here is that when that method is present trail/tapestry/hibernate don't automatically add the object to the set anymore!!!
You notice this when you add a related object in trails, and it doesn't show up. At all. No error. Everything normal.

The solution is of course to add the following line to the end of the method;

"members.add(member);"

and all will be well.

9)

So you want to store byte arrays in the database, do you? Maybe a picture or two? Hmmm?? OK, the most important stuff first. You have to use the @Lob annotation on the getter of the byte[]. If you haven't done it yet and have had problems, you'll have to drop the database and recreate it.

That makes it possible to even store byte[]s at all. They can't be very large, though. IIRC MySQL have a default limit of 64K and if you know how to get around that easily, drop me a line.
The next problem is that you have to make you own service to show the Images, let's call it an ImageService. It's very well described in the Tome of Kent at http://agileskills2.org/EWDT/&nbsp;But if you peek abit at the provided and downloadable sourcecode at http://agileskills2.org/EWDT/source.zip&nbsp;You'll find an example in the 'Album' app.

Labels

 
(None)
  1. Oct 03, 2007

    The Earl says:

    9) MySQL's BLOB and TEXT types are 64K. You can use a MEDIUMTEXT or a MEDIUMBLOB...

    9)

    MySQL's BLOB and TEXT types are 64K. You can use a MEDIUMTEXT or a MEDIUMBLOB for 16M, or a LONG<> for up to 4G. It may be possible to modify the database behind Hibernate to extend the field w/o actually telling hibernate about the new size, but no guarantees that something in the middle won't break if you give it 4Gb of data to pass .

     For a simple bit field, it would be smaller to use a TINYTEXT or TINYBLOB which are 255 bytes.