Archive for September, 2011

September 23rd, 2011
3:17 pm
Preventing Overflow with long strings in table cells

Posted under JSF
Tags , , , , , , ,

I hit this issue when displaying email addresses in a p:dataTable.

The problem is that for long strings without spaces, the browser tries to enlarge the table cell width, causing the table to stretch beyond the correct bounds and messing up the layout. A column will wrap and enlarge vertically, but this will only be done when it can break on a space. Setting the widths for the columns is technically just advisory on the browser and may be overriden if needed.

There are various solutions to this, and this post here in Stack Overflow discusses them.

My chosen solution in this case was the following:-

  • Place the text in the cells in <spans>, to allow them to be styled with CSS. You could also style the column <td> cells by applying style/styleClass attributes to the p:column tag, but this will limit your flexibility – for example if you do this p:column does not expose the title attribute on the <td> (see below)
  • Style the <spans>  with display:inline-block;overflow:hidden. This allows a width to be set for the span (I used the same width as set for the column), and hides any overflow (which would otherwise bleed into the next column).
  • Text will still wrap on spaces if they are present, but long strings without spaces, such as email addresses or file paths, do not cause a problem, but they will truncate and so will not be fully visible by default.
  • I include a title attribute on the span to include the full text. This allows the full text to be displayed on hover for any long strings that are truncated in the cell.

This neatly solves the problem, and prevents the table layout messing up.

No Comments »

September 23rd, 2011
2:12 pm
Using Non-blocking spaces in xhtml

Posted under HTML
Tags , , ,

Occasionally this is useful – I had to do this when I wanted to adjust the spacing in a Primefaces p:dialog header. The header text can only be set via an attribute which does not allow any markup to be used (a header facet is not currently available for a p:dialog).

The old &nbsp; entity does not work in xhtml as it is deprecated.

The solution is to use the Unicode equivalent directly, which is &#160;

My previous related post about using Unicode characters in HTML may be found here.

No Comments »

September 23rd, 2011
1:21 pm
JPA – Using a mapped superclass to hold Ids and Version Numbers for all Entities

Posted under JPA
Tags , , , ,

All my entities have a numeric ID as a primary key, except in very exceptional cases. In particular, I never used business data as part of the primary key, nor do I ever use a primary key for any business purposes (such as an invoice number). I consider that primary and foreign keys are only used to define relationships, i.e. they are metadata as far as the domain model is concerned.

The problem of using business data in primary keys is that if the business data format for a primary key changes in any way, all the foreign keys referring to this primary key column must also be changed. This can result in massive changes throughout the data model for what started as a simple business change. Taking the above invoice number for example, the business may decide to add an alphanumeric branch prefix to the invoice number.

If instead all primary keys are kept as separate numeric IDs, changes to the format of business data should typically only require changes to one table.

With that rant out of the way, the main point of this post is that, given the above, plus the need to hold version numbers on all entities to support optimistic locking, it is desirable to hold all the primary keys and version numbers in a mapped abstract superclass. This has the following benefits:-

  • the entities are simplified and the key/version number implementation is encapsulated and centralised, which is a good design principle
  • the mechanism allows for a standard mechanism to get the primary key/version of any entity polymorphically via the mapped superclass. This is especially useful when you need to do comparisons between entities and you do not want to override equals on the entities. It is also useful for other polymorphic situations – in my case I also have a polymorphic tree implementation which makes use of this

Note the following points about the implementation:-

  • As I have discussed here, I always annotate getters rather than fields, to permit inheritance. In this case, I provide fields plus polymorphic getters/setters in the mapped superclass for getEntityId and setEntityId which are marked transient and are not annotated. They are purely to allow polymorphic access to the primary key.
  • Each entity defines its own getters/setters with a mnemonic name for the primary key. These getters/setters call the base polymorphic ones. The reason for this is that as well as improving the key naming,  it allows each entity to annotate its primary key differently, for example to use a specific generator for sequences etc.
  • As the primary keys are annotated in the subclasses, this permits the base superclass IDs to be generic. In my case, this caters for both Long and Integer primary keys using a generic base superclass. Note that it would not be possible to annotate in the superclass if the ID is a parameterised type – JPA spits this out and will not allow it.
  • Due to the above generic issue, the type for the version number must be fixed, as this is annotated in the superclass. In my case I settled for an int for version numbers.
  • Note that as the primary key is generic, it must therefore be a reference type rather than a primitive type (e.g. Long rather than long). In my case, primary keys are normally Long
  • In some cases, I have other mapped superclasses, such as Tree and TreeNode classes. In this case, Tree and TreeNode extend the EntityBase class, and Tree and TreeNode subclasses then just extend Tree and TreeNode respectively.

The following code illustrates a simple example of the superclass and an entity subclass:-

 

EntityBase

/**
* Entity implementation class for Entity: EntityBase
* This mapped superclass defines the primary key and locking version number for all entities.
* The getters/setters are marked transient so they are not mapped here. This allows polymorphic access to primary key (and version),
* but still allows the subclass to define its own (mapped) getter/setter names for the primary key, and to annotate for specific generators etc.
* This allows meaningful names for primary keys, normally <tableName>Id
*/
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class EntityBase<C> implements Serializable {
    private static final long serialVersionUID = 8075127067609241095L;

    private C entityId;
    private int version;
   
    @Transient public C getEntityId() {
        return entityId;
    }
    @Transient public void setEntityId(C entityId) {
        this.entityId = entityId;
    }
    /*
     * The version cannot be generic as it is annotated here (unlike the primary key)
     * If you do, Eclipselink throws a tantrum. In practice, an int is plenty –
     * it would allow continuous version changes once a second for over 68 years for example.
     */
    @Version
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }
}

 

Address

@Entity
@Access(AccessType.PROPERTY)
public class Address extends EntityBase<Long> implements Serializable {
    private static final long serialVersionUID = 3206799789679218177L;
   
    private int latitude;
    private int longitude;   
    private String streetAddress1;
    private String streetAddress2;
    private String locality;
    private String postTown;
    private String county;
    private String postCode;
       
    public Address(){}

    @Id
    @GeneratedValue(generator="AddressId")   
    public Long getAddressId() {return super.getEntityId();}
    public void setAddressId(Long addressId) {super.setEntityId(addressId);}
   
    public int getLatitude() {return latitude;}
    public void setLatitude(int latitude) {this.latitude = latitude;}
    public int getLongitude() {return longitude;}
    public void setLongitude(int longitude) {this.longitude = longitude;}
   
    public String getStreetAddress1() {return streetAddress1;}
    public void setStreetAddress1(String streetAddress1) {this.streetAddress1 = streetAddress1;}
    public String getStreetAddress2() {return streetAddress2;}
    public void setStreetAddress2(String streetAddress2) {this.streetAddress2 = streetAddress2;}
    public String getLocality() {return locality;}
    public void setLocality(String locality) {this.locality = locality;}
    public String getPostTown() {return postTown;}
    public void setPostTown(String postTown) {this.postTown = postTown;}
    public String getCounty() {return county;}
    public void setCounty(String county) {this.county = county;}
    public String getPostCode() {return postCode;}
    public void setPostCode(String postCode) {this.postCode = postCode;}   
}

No Comments »

September 23rd, 2011
12:18 pm
Re-queuing JSF Events

Posted under JSF
Tags , , , ,

This is a very simple and powerful technique which can provide an easy solution to a number of event issues.

The case in point was where I wanted a value change event on an input component (a check box) to behave like an action event.

The value change event will normally fire after validation (after the Process validations phase). In my case, I wanted the event to be fired at the Invoke Application phase, as would happen with a button click. In other words, I wanted my checkbox to behave more like a button.

Whilst there are other ways around this  kind of issue, they often involve messing with the JSF life cycle by using immediate components/calling render response early etc. and typically have other side effects. For example, in a Value change event you will not see the results of the bean setters being called as this has not happened yet, so you end up having to make JSF calls to manually update values early etc.

Instead, a value change event can easily be re-queued to occur in the Invoke Application phase. The beauty of this is that you are relocating the event rather than messing with the JSF lifecycle, which means that the event happens in the context you want it to, and everything is set up correctly.

To requeue an event, you must detect when it fires the first time, and then requeue it. When it fires the second time, you detect this again and perform the action that you desire.

Here is a code sample which does this:-

    public void showInheritedListener(ValueChangeEvent event) {

        /*
         * Requeue this event to the Invoke Application phase so it behaves like an action
         * This ensures that all the model values have been updated.
         */
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
               log.fine(this+":showInheritedListener: oldValue="+event.getOldValue()+", newvalue="+event.getNewValue());       
            boolean newValue = (Boolean)event.getNewValue();
            changeInherited(newValue);
        }
        else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }       
    }   

An important point to note is the use of event.getPhaseId() to detect which phase the event is currently being called in. In particular, when it is first called after the Process Validations phase, it is important to note that event.getPhaseId() will return PhaseId.ANY_PHASE, which is not expected or intuitive. You will see from the above code that by handling the first call to the event in the else clause of the if, we only have to test for the second call, when event.getPhaseId() will return PhaseId.INVOKE_APPLICATION as you would expect.

This technique is clean and simple to use, and does not suffer from unwanted side effects that other solutions have. It is well worth taking note of.

No Comments »