Eclipse in Styleby Daniel Spiewak
Beyond development, beyond usage

An Easier Java ORM

Posted by Daniel Spiewak on July 18th, 2007
Categories: Java, Ruby
Tags: , , , , , ,

Moved to: http://www.codecommit.com/blog/java/an-easier-java-orm

Add to DZone

14 Responses to “An Easier Java ORM”

  1. Eelco Hillenius Says:

    Interesting stuff Daniel! Could you provide more details on how that looked in your Wicket based project? Would a integration project (ActiveObjects Wicket) be an idea?

  2. Eelco Hillenius Says:

    How about things like first level cache (for efficiency and to detect cycles)? And do you force users to use interfaces or can they use normal classes? And why didn’t you choose for a Entity annotation rather than an interface?

    I guess I’ll have to check out the sources myself first, huh? :)

  3. David Marko Says:

    I would really appreciate additional info for SaveableEntity and for some further features that are inside. Lacking ActiveRecord style ORM on JAVA keep us on Rails. This can direct us back to JAVA. Syntaxt of ActiveObject is amazingly easy to adopt and flexible. What are the planned features you are thinking about. Can you imagine some implementation of migrations for instance?

    Thanks a lot for this project
    David

  4. Ganeshji Marwaha Says:

    Pretty Neat stuff… I understand that this is just in 0.3 version, but still, i am not very comfortable with the interface approach, primarily because it is far easier to generate getters and setters from instance variables than to write both getters and setters by hand…

    I guess, there should be a better solution for that.

    -Ganesh

  5. Daniel Spiewak Says:

    @Eelco

    Yeah, I’m planning on writing an article in the near future talking about how I’m using AO within Wicket. Most of my custom code AO-Wicket relates to the fact that Entities aren’t serializable (since they’re just cached database peers) so special care needs to be taken with models and listviews. It’s fairly straightforward stuff, but I’d love to get the integration closer where possible. This is an area where I have interest, but no clear idea as to what form an integration project would take. Maybe I should look at the Wicket-Hibernate project… :-)

    Re: interfaces vs classes: Unfortunately, Java interface proxies only work with interfaces, and not with implemented classes. AO does allow for property change listeners (Java Bean Spec). More usefully, it also allows for custom implementations of methods (ala ActiveRecord method overrides), but I’ll freely admit that the syntax is perhaps a little unintuitive.

    I thought about using an entity annotation to just tag entity interfaces rather than extending a predefined interface. But by extending Entity, all entities can inherit methods like getID(), setID(int), getTableName(), addPropertyChangeListener(PropertyChangeListener), etc… rather than having to define these methods in every entity interface. SaveableEntity is a better example of this, since it defines a save() method to execute any pending UPDATEs.

    @Ganeshji

    Yeah, I’ll freely admit that the major downside to ActiveObjects is it still has a lot of boiler-plate (though still less than POJO-based ORMs). Fortunately, writing getter and setter signatures by hand isn’t too terrible. I’d love to cut down on this boiler-plate still further, but unfortunately Java’s inherent limitations prevent us from going as far as an ActiveRecord-style method_missing.

  6. richard Says:

    Where would you code a business rule like “every person must have a house” or “every person must have a name which may not be blank”?

    Your api is a way of persisting a set of data transfer objects.

    Hibernate allow one to persist a set of domain model objects that contain the system business rules - which is a hudge difference.

  7. Eelco Hillenius Says:

    You don’t have to limit yourself using normal normal JDK proxies though. There are plenty of project that use e.g. cglib to create dynamic proxies using byte code manipulation. Amongst others Hibernate and wicket-ioc.

  8. Eelco Hillenius Says:

    Maybe Databinder (http://databinder.net/site/show/overview) is something to look at when thinking about an integration project. I’m not sure either. But as you’re trying to cut the ammount of code you need to write, it probably should provide some very convenient models and transaction utilities.

  9. Eelco Hillenius Says:

    Sorry for spamming, but another thing to look at - if you’re interested - is the phonebook example (http://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicket-phonebook). That’s an example project that shows how you *could* use Hibernate, Shades or iBatis with Wicket. And maybe ActiveObjects sometime as well :)

    Drop me a line if you want write access to wicket-stuff.

  10. Daniel Spiewak Says:

    @richard

    Well, you’ve got two choices for the example you gave. You can define the database schema attributes to not allow nulls in the houseID field:

    public interface Person extends Entity {
    // …

    @NotNull
    public House getHouse();
    @NotNull
    public void setHouse(House house);
    }

    Or for a more complex rule, you could use AO implementations, which are definitely weird, but quite powerful. I’ll make sure I cover them in a future post.

    @Eelco

    I’ll take a look at those wicket sources. Since I’m working on a project using Wicket and ActiveObjects, it’d obviously be nice to make the integration as tight as possible.

    I’ll have to look at cglib and similar. I briefly considered byte-code manipulation when designing the framework, but that always required weird hacks like custom classloaders etc… While I don’t have a problem writing framework internals which do weird stuff, I don’t want the API to be too bizarre. :-)

  11. Daniel Says:

    Have you taken a look at BeanKeeper before?

    http://www.netmind.hu/persistence/

    It’s another persistence library with a similar philosophy - zero configuration, no boilerplate code, no administration, etc. I’ve used it a bit in the past, and it’s really quite cool how it magically stores and loads objects without any ugly ORM code or configuration. If you are familiar with it, what would you say are main advantages of ActiveObjects over BeanKeeper?

  12. Daniel Spiewak Says:

    @Daniel

    No, I wasn’t familiar with it actually. It does seem interesting though. My three problems with it just from reading bits of the tutorial:

    * Still requires a lot of boiler-plate code (it’s POJO based)
    * Has it’s own query syntax (HQL is a big reason I avoid Hibernate)
    * Seems to be List based for relations, rather than the more intuitive (and performant) array based

    The problem with POJO-based frameworks, beyond the added boiler-plate, is that everything must be eagerly loaded. Basically, you turn every entity retrieval call into a SELECT * Hibernate can get around this with bytecode manipulation, but personally I’m a little leery of letting random frameworks peer into my class internals.

    In ActiveObjects, every value is lazy-loaded and cached. So you use a minimal amount of memory for each entity.

  13. Daniel Says:

    Thanks for the response. Regarding your comments:

    *** Still requires a lot of boiler-plate code (it’s POJO based)

    I may be misunderstanding something here. In BeanKeeper your class definition would be:

    public class Person {
    private String firstName;
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    }

    In ActiveObjects your class (interface) definition would be:

    public interface Person extends Entity {
    public String getFirstName();
    public void setFirstName(String firstName);
    }

    So, by “boilerplate code”, are you referring to the implementation of the getters and setters? I suppose it is a bit of extra code, but at the same time, being able to use POJOs like this gains you a lot of flexibility:

    - You can easily add custom code to your getters and setters
    - Works well to persist existing/legacy classes
    - External users of your entity classes do not have know or care about the persistence manager, they just create and use POJOs like any other object

    I suppose the above may just be general benefits of doing things the POJO way. Anyway, for my particular project, the above points were quite important - I’m sure there are cases where they are not as important (e.g. starting a new project from scratch).

    *** Has it’s own query syntax (HQL is a big reason I avoid Hibernate)

    Doesn’t AO have its own query syntax too? BeanKeeper queries don’t seem all that different from AO queries to me, for example:

    manager.find(Person.class, “name LIKE ? OR age > ?”, “Joe”, 9); // AO
    store.find(”find person where name LIKE ‘Joe’ OR age > 9″); // BK

    *** Seems to be List based for relations, rather than the more intuitive (and performant) array based

    BeanKeeper’s lazy lists are actually the primary reason I used the library for a previous project - you can execute queries that return huge lists with very low memory usage. By using the List interface instead of arrays, BeanKeeper can page objects into memory only when they are actually accessed. This sort of feature is really useful for reporting, where you may be dealing with queries that return hundreds of thousands of objects.

    BTW, what is the reason that arrays are more intuitive? Doesn’t everyone these days use Collections instead of arrays (unless you’re doing some low-level stuff)? Regarding performance, it seems unlikely that there would be any noticeable difference between using arrays and Lists for an ORM library.

    *** In ActiveObjects, every value is lazy-loaded and cached. So you use a minimal amount of memory for each entity.

    Agreed, this is a benefit of using an interface and not a POJO. On the other hand, if you do need to access all the data in an object, it is more efficient to do a single SELECT * than to execute many smaller queries. The memory use of a single object does not typically cause too many problems - it’s normally only when you have thousands of objects in memory at the same time, and the BeanKeeper lazy lists address this issue quite well.

    I’m definitely looking forward to trying out ActiveObjects soon. I have a few small BeanKeeper test programs, so it’ll be interesting to re-implement them with ActiveObjects and compare the code and results.

  14. Daniel Spiewak Says:

    Well, I’ll grant you that boiler-plate POJO vs Proxy is probably about equal. I suppose at some minimal level, the compiler still has to be satisfied. And as pointed out earlier, the POJO approach has the major advantage in that all getters and setters can be generated from fields.

    AO actually doesn’t have it’s own query syntax. It’s just using PreparedStatement fragments. For the example you gave, the fragment of “query text” is actually concatenated directly into an SQL query, like so: “SELECT id FROM person WHERE ${query_text}”, and then executed with the specified parameters. I didn’t look, does BK actually use PreparedStatements? And if so, how effectively? This is a really important issue, especially for databases like Derby or Oracle which rely heavily on PS and have lousy performance without them.

    Point taken on the SELECT * vs lazy load. Actually, it’s possible in AO to do this sort of thing (I added the functionality like two weeks ago, so like most things it isn’t documented yet). The code would look something like this:

    manager.find(Person.class, Query.select(”*”).where(”name LIKE ? OR age > ?”, “Joe”, 9));

    Query is just a preparedstatement builder class which allows things like: Query.select().where(”name = ?”, “Bill”).limit(5).order(”name̶ ;) => “SELECT id FROM ${table_name} WHERE name = ? ORDER BY name LIMIT 5″. The idea behind it is that it mimics the ActiveRecord find() syntax a bit, through the filter that Java doesn’t have symbols like Ruby.

Leave a Reply