BibleGateway.com Verse Of The Day

Showing posts with label SEAM. Show all posts
Showing posts with label SEAM. Show all posts

Wednesday, October 13, 2010

A Few More SEAM Nuggets

I just came across some stuff that was supposed to be a blog post with some more SEAM tips and tricks. Since then, I've moved on to a new job, and haven't been using SEAM in my new position.

Showing Number of Matched Records in List View

When you generate a SEAM application from a database, you end up with a set of components for each table - for example a list view, record view, and record edit. When you are displaying a list of records, it is common to want to show how many records match the current query (or the total records if you went to list view without a search criteria).

You can easily get this function by accessing the "resultCount" attribute on your view, like this:

<h:outputtext value="#{yourTableList.resultCount} rows found." rendered="#{not empty yourTableList.searchResults}">

Change Default Sort Order, But Still Allow Click-To-Sort

One requirement we ran into on one of my SEAM projects was to change the default sort order for some of the list views. However, the views that the SEAM gen tool creates allows the user to click on the column headers to change sorting as well. To achieve a default sort order on initial load, and still allow clickable headers, override the getOrder() method in your List.java source like this:

@Override
public String getOrder() {
String order = super.getOrder();
if ("".equals(order) || order == null)
{
order = "col1 asc,col2 desc";//your default sort columns here
}
return order;
}


Wednesday, July 15, 2009

More Jboss SEAM Nuggets

As I dig farther into the Jboss SEAM world, I figured I would share a few nuggets of info as I find them. It's more notes than tutorial, so don't expect too much....


ORACLE TIMESTAMP ISSUES

If you are using Oracle, more specifically Oracle 9i and newer, you will probably have issues with date fields. There was a change in Oracle's JDBC driver somewhere between 8i and 9i that changes how the driver reports a DATE field in the metadata. Anyways, running seamgen gets you entities with Date objects with annotations like @Temporal(TemporalType.DATE).

When you go to deploy though, The validation fails because it is expecting a TIMESTAMP field, but gets a DATE field. That keeps the EJB from deploying and keeps the EntityManager from being bound.

Luckily, there is an easier fix than manually updating the data types and annotations in all your generated entities. You can add the following JVM argument to your startup to force the Oracle driver to report DATE fields based on the Oracle 8 driver behavior instead of the 9i+ driver:
-Doracle.jdbc.V8Compatible=true


RENDERING ISSUES ON SERVER

Speaking of JVM args, I noticed on my dev box (Windows), my SEAM app rendered beautifully. When I deployed to the Linux server, some of the fancy "3d" type components suddenly looked flat. There were exceptions in the log for some Swing classes (sorry I don't have the exact exception or stack trace, it was a while ago). Why is it using Swing to render page elements? Don't know, and at this point, don't care, as long as there is a simple fix. And alas, there is...

I added the following JVM argument to my Jboss startup to let it know it's a headless server. Seems to have fixed my issue.
-Djava.awt.headless=true


MULTIPLE PAGE DEFINITIONS FOR ONE PAGE

When you build out a new application using seamgen, you will notice that for each entity, you will have several view components. For example, you will have a TableName.xhtml and a TableName.page.xml file. The *.page.xml contains your <page> definition, that will define the view id, parameters, conversation settings, etc.

You will also notice that the SEAM pages.xml file also has (or can have) <page> definitions. Guess what, the pages.xml definition for a given page, if it exists, overrules the *.page.xml version. Remember that when changes you make to *.page.xml don't seem to take effect, or other odd behavior where those values seem to be ignored.

It's not a hierarchy, it's not an inheritance, it's a one-or-the-other situation. It caused me quite a bit of grief until I figured that out.



USING SEAM COMPONENTS FROM SERVLETS

So you need to throw in some regular old-school Servlet's into the mix? But you want your SEAM goodies too? Damn, you just want the best of everything.

There are a few ways to do it, and I found the easier way is to "wrap" your Servlet(s) in the SEAM filter. Add a line something like this to your SEAM components.xml file (make sure to change your URL pattern appropriately. In my case my Servlet is to download a CSV file).
<web:context-filter pattern="/csv"/>
And then in your Servlet code, you can get your SEAM stuff from the Components object like the sample below:
UnmappedAccount unMapAcct = (UnmappedAccount)Component.getInstance("unmappedAcct");
In this example, UnmappedAccount is a class in my EJB module annotated as a SEAM component.
import org.jboss.seam.annotations.Name;
...

@Name("unmappedAcct")
public class UnmappedAccount { ... }


CASCADING EJB'S

Allow me to throw out a minor warning on the generated SEAM code. The default CascadeType in the generated EJB's is "ALL", as seen in the annotation below.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "...")
It's not devastating, it's not a bug, but it is something you should be aware of in case you don't want cascading (or worse, aren't aware of cascading and what it really means, and just happily go with the defaults).

See http://java.sun.com/javaee/5/docs/api/javax/persistence/CascadeType.html for more information on the various CascadeTypes, in case you don't already know. If you don't want cascading, remove the "cascade = CascadeType.ALL" portion of the generated annotation.

Let's say you try to delete a record that has children records attached to it. You might expect to get an error back saying you can't delete a record that has children attached. That's what you would get from, say TOAD or Squirrel or SQL-Plus, or even from applications written using plain old ODBC or JDBC statements. But with cascading, that delete will happily take care of those children for you without complaining ;-)



NAMED QUERY DEFINED IN COMPONENTS.XML

I just found this one, and it seems to be a good fit with what I have to do right now. I haven't finished it yet, so not much to share here yet. Once I get that working, it might be worth mentioning in my next nuggets post.

Thursday, May 28, 2009

Emergency Startup CD for Windows

BartPE, because sometimes you actually have to run Windows.

If you have Windows and your system did not come with a "rescue", "restore", or "emergency startup" type CD (yes, I'm talking to the cheap bastards at Dell who don't include the Windows CD), then you NEED to follow the instructions at http://www.howtohaven.com/system/live-windows-rescue-cd.shtml. This creates a bootable "BartPE" CD with all the right utilities for fixin' what ails ye.

Do it now! Before you need it, not after. I learned the hard way, and after this past week, I can't sing the praises of BartPE enough. It was a life saver.

My wife's laptop booted to a BSOD when I was trying to VPN in to work. Oh well, a night off....but then it kept doing it, over and over. I couldn't get Windows to start for the life of me.

Since I didn't have a bootable Windows CD, I was left trying to boot FreeDOS from my thumbdrive (using LiveUSB Creator) . I made sure to have a copy of NTFS4DOS installed on there as well, and ran through some exercises where I got a command prompt to manually copy registry files around. That was painful, but it actually worked enough to get the machine to boot into XP. But it was a version of XP that had all sorts of issues, error messages, drivers crashing, no USB support, no CD recording, no network, etc. Without USB, network, or CD burning, I couldn't get our important files off the machine.

Anyway, to make a long story short, the FreeDOS/ntfs4dos route was crappy and painful with no real reward.

The BartPE rocks the house! It boots into a minimal XP interface with all the right utilities for fixing your issues, and USB drives are recognized, so I can copy important files off the machine in case I feel the need to wipe it clean.

I guess I really should do regular backups, but what fun is that? Preventing problems is boring, solving problems is heroic....

Tuesday, March 03, 2009

An Overzealous SEAM Validation

I am using the Jboss SEAM framework for the project I am currently working on. The first thing that really bit me was a validation on single character fields that seems a bit "too stringent". I'm sure I'm not the first to run into this. In fact it may be fixed by now in a newer version of SEAM, but figured it's worth a post anyways.

When you use Jboss Developer Studio (JBDS) to reverse engineer your database (I imagine the seam-gen tools do the same since JBDS uses them), the getter method on the EJB looks something like this...

@Column(name = "DEFAULT_REMAP_IND", length = 1)
@Length(max = 1)
public Character getDefaultRemapInd() {
return this.defaultRemapInd;
}
Looks fine, looks reasonable. Single character fields are often used for flags or indicators, as this one above is -- it's a simple Y/N field. So in my XHTML I use a radio button control instead of a free form text field.

<h:selectOneRadio id="defaultRemapInd" value="#{ocamCustTypeDfltHome.instance.defaultRemapInd}" required="true">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<a:support event="onblur" reRender="defaultRemapIndDecoration"/>
</h:selectOneRadio>

The SEAM framework will use that @Length annotation to perform some field validations for you automagically, which is pretty cool as it can be a real time-saver. But the funny thing is that when this "max length of 1" validation fires, you get the lovely message shown in this partial screen shot ....

Not sure how to get a single character with a length greater than 0 but less than 1, but I do know that the easiest thing to do in this case is remove the @Length annotation for that field. I had to do that for a few different tables. Luckily they were all flags that could be replaced with radio buttons, but in the case where you had to allow free input, you might have to get more creative (you can always put a max length on the input text field).

For reference, I am using Jboss 4.2.2, SEAM 1.2GA, Jboss's EJB3 implementation (which is Hibernate under the hood), XHTML and Facelets for the views. Like I said, this might be fixed in a later release of SEAM.