Patterns in Software

Welcome to Ninth Avenue. Here you will find articles, howtos and bug fixes for server-side webapp development with Java EE, JSF, Unix and CSS.

JPA CascadeType.REMOVE vs Hibernate @OnDelete

By , 13 June 2014

Somehow database models and ORM always end up being more difficult than you expect. Here is a common source of confusion between JPA cascade operations and database cascade operations. Basically they do the opposite thing. For example:

public class House {

    @OneToOne
    Object door;
}

If you use CascadeType.REMOVE then deleting the house will also delete the door (using an extra SQL statement).

    @OneToOne(cascade=CascadeType.REMOVE)
    Object door;

If you use @OnDelete then deleting the door will also delete the house (using an ON DELETE CASCADE database foreign key).

    @OneToOne
    @OnDelete(action = OnDeleteAction.CASCADE)
    Object door;

JPA has not standardized the ON DELETE and ON UPDATE foreign key actions possibly because they are SQL-specific and JPA is supposed to be storage-agnostic. I think this is unfortunate - what I'm looking for is ON DELETE SET NULL which would mean that when I delete the door, House.door gets set to null automatically. It's a fairly common requirement and is implemented in OpenJPA like this:

    @OneToOne
    @ForeignKey(deleteAction=ForeignKeyAction.NULL)
    Object door;

For the moment it looks like I'll have to stick to OpenJPA. Not sure why this isn't an option in Hibernate.

No comments yet, be the first to comment!

OrmLite DAO Factories And Connections Made Easy

By , 7 June 2014

OrmLite comes with some classes to help manage connections, but unfortunately they are poorly named and just plain confusing. For example, OpenHelperManager manages connections - and see if you can guess how that relates to OrmLiteSqliteOpenHelper or the DaoManager. This short blog gives you some simple code to make your API more intuitive and readable.

Connection management and singleton objects are never a simple combination. That's why we do things like abstraction and encapsulation. What I set out to do was have an API that looked like this:

    CategoryDAO dao = CategoryDAO.connect(context);
    List categories = dao.getCategories();
    dao.release();

To get there it helps to know what is going on under the hood. So let's reverse engineer some of those oddly named OrmLite classes:

  • OrmLiteSqliteOpenHelper (Database Definition). Defines how to connect to the database and create and update the tables. This is where the real connection object lives. 
  • OpenHelperManager (Connection Management). Keeps count of the number of times the database (connection) has been requested and released. When the count goes to zero it releases the database resources and when it goes back up it recreates them.
  • DaoManager (Singleton Management). Ensures that only one instance of a DAO is created for a given connection. Most apps will only connect to one database, so this effectively implements a singleton pattern. It is necessary because creating DAOs is expensive in Android due to the reflection involved.

Now, we can tie these objects together to implement the API we'd like. Here's an example:

public class CategoryDAO extends BaseDaoImpl<Category, Integer> {
    public CategoryDAO(ConnectionSource source) throws SQLException {
        super(source, Category.class);
    }
 
    /**
     * Static instantiation methods. The database connection is accessed via
     * the OpenHelperManager which keeps a count of the number of objects
     * using the connection. Thus every call to connect() must be matched by
     * a call to release() once the session is done. 
     */
    public static CategoryDAO connect(Context context) {
        return with(OpenHelperManager.getHelper(context, Database.class)
                .getConnectionSource());
    }
    public static CategoryDAO with(ConnectionSource connection) {
        try {
            return (CategoryDAO) DaoManager.createDao(connection, Category.class);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Releasing the DAO flags the connection manager that the DAO is no
     * longer using the connection. When the connection count is zero, the
     * connection manager will close the database.
     */
    public void release() {
        OpenHelperManager.release();
    }
}

Now our target code above will run, OrmLite will manage the singletons and the OpenHelperThingy will reuse connections across the DAOs.  The alternative factory method CategoryDAO.with(connection) is useful for unit tests, or for using one DAO inside another like this:

    @Override
    public void update(Category category) {
        super.update(category);
        NoteDAO.with(connectionSource).updateColors(category);
    }

Here, we just reuse the same connection as the host DAO. For a unit test, you can set up the connection to the test database manually (or use Robolectric to mock the Android context).

Let me know if you think there is anything wrong with this pattern in the comments below. In my experience readable code goes a long way.

No comments yet, be the first to comment!

How To Make Android Spinner Options Popup in a Dialog

By , 28 May 2014

The earlier versions of Android always showed spinner options in a dialog. Then I think devices got bigger and the powers that be decided to use a dropdown list for spinner options instead of a dialog. It's a sensible choice because the dropdowns look and operate better than the dialog - sometimes.

It's the sometimes that is the problem. For lists with a lot of data it makes better sense to use a full screen dialog than a small dropdown. The screenshots below show how much better the usability of a dialog selection is for our app, The Game Of Your Life.

Read more...

No comments yet, be the first to comment!

How To Remove The Facebook Android Sharing Intent

By , 2 May 2014

I don't really care why Facebook made a mess of their Android sharing intent. Other developers have already pointed out that their iOS sharing works fine, but their Android product only allows you to share URLs and not text. My guess is they are trying to force developers onto their API because, you know, force makes people so much more motivated and creative and all that.

Whatever.

The real problem is that it makes your app look broken, and fortunately there is a simple solution:

Dump Facebook.

Just cut and paste the code below to launch your share intents and Facebook will not be listed as an option. That way you won't look bad when their share page comes up blank.

Read more...

No comments yet, be the first to comment!

How To Catch A ClassNotFoundException

By , 13 April 2014

HTTP request from spammers trying to exploit our commenting system is causing a ClassNotFoundException deep in the JSF / Java code. Specifically, spammers are sending serialized objects in the javax.jsf.ViewState parameter for classes that no longer exist in our system. The resulting exception is this:

Read more...

No comments yet, be the first to comment!

Comparison Of Cloud Storage / Backup Services

By , 17 January 2014

The company that was storing our backups online was always a little flakey and recently the scripts just started failing altogether. Time to find a new backup service methinks.

Since I first looked at backup online the market has changed a lot. It's now called "cloud storage" for starters, and the number of companies providing competing services has ballooned.

Here is a quick comparison a few key players on the market, and the monthly cost of storing 100GB of backups. The server being backed up is running Ubuntu, so the last column shows how the backups are run. Rsync is our preferred method.

Read more...

No comments yet, be the first to comment!

Embed Code Plugin For FCKEditor

By , 17 November 2013

Here's a plugin I just whipped up for FCKEditor which makes it easy to add embedded HTML code such as YouTube and Vimeo videos.

FCKEditor Embed Plugin Dialog

To install, download the plugin below and unzip it in your plugin folder. Then add the following line to your fck_config.js:

FCKConfig.Plugins.Add('embed');

You will also need to add an 'Embed' entry to your toolbar array in fck_config.js.

Download the FCKEditor Embed Plugin Now.

One problem you should be aware of is that browsers now try to protect users from XSS (Cross-Site Scripting) injection, so if you send iframe tags in the embed code, they might get stripped out. To fix this problem, you need to ensure your server adds the following header:

X-XSS-Protection: 0

 

3 comments, post a comment!

How To Export Google Reader Feeds Into Opera

By , 19 March 2013

Everyone is up in a storm since Google announced they were killing Google Reader. Although I liked Google Reader, I believe change creates opportunities and unsurprisingly a better solution for feed reading presented itself almost immediately. In fact it was already installed on my system.

It's called Opera.

I installed Opera to read email when Mozilla killed Thunderbird and after some heavy customisation I'd say it works pretty well. It's much faster than Thunderbird for a start.

Now it looks like Opera is not only going to save my RSS feeds, but make my news reading more organised thanks to it's flexible user interface.

So here is a quick howto with screenshots for people who need to get off Google Reader and want to try out Opera.

Read more...

1 comment, post a comment!

Preserving JSF Request Parameters and REST URLs

By , 13 February 2013

Have you ever used a URL pattern something like this?

http://localhost/app/widgets/WidgetEditor.xhtml?id=300 

or perhaps this?

http://localhost/app/widgets/300/edit 

Well, as a JSF developer you've probably already realized a little problem. How do you remember the id from request to request? There are a few simple solutions.

Read more...

6 comments, post a comment!

How To Get The HTTP Status Code In Selenium WebDriver

By , 16 November 2012

One of the first things you'll notice when you start testing your web application with Selenium WebDriver is that there is no API to get the HTTP status code for a page. If you want to know why, you can go and read WebDriver issue #141. Personally I don't care why - I just want to test my HTTP reponse codes (especially 403 Permission Denied).

There is a fairly simple workaround you can use for WebDriver, but firstly lets look at how to do it without WebDriver. Nobody said you HAVE to use Selenium right?

Read more...

6 comments, post a comment!

1 2 3 4 5 6 7 8 9 10 11

Join The Mailing List

Subscribe to our mailing list for the latest news and announcements.

Follow Ninth Avenue

Website Updates