Seam EntityHome Design Pattern

Home/Java/JBoss/Seam/Seam EntityHome Design Pattern

I’ve been using Seam for over a year. At some point the “Home” object was introduced to the documentation (Chapter 11). Reading the documentation didn’t convince me of the point. Being an ATG guy at heart, I still prefer using “form handlers” for managing my important entities. So I haven’t bothered.

However, just recently I ran into a little problem with LazyInitializationExceptions. I’m sure you’ve run into them yourself. Basically, when Hibernate loads an entity for you, it’s loaded by an entity manager which is available to manage that object within a specific scope. This effects persisting changes. Also, if you have properties on that entity that have a fetchType.LAZY, those properties can only be lazily loaded while the same entity manager is available. If it’s not, you get LazyInitializationExceptions. No fun.

So in Seam, what I usually do to avoid this, is to create a long running conversation, and load the entity within the context of that conversation. Then, as long as you’re still in that long running conversation, you can lazily load all the properties you want.

Normally this is fine. However, in my latest project the application will send e-mails to users when they get a new inter-user message. If they click on the link in the e-mail, they come to the site, but without the existing long running conversation query parameter. Their user component is session scoped, so they’re still logged in, but the user object is now outside of it’s conversation, and if you attempt to access lazily loaded properties, for instance the user’s messages they are trying to see based on the e-mail, blammo: exception central. Unhappy users.

I was pointed to this page: Using EntityHome for entities in long-running contexts

Which showed me how to use the EntityHome to avoid the whole problem. Basically it works like this:

When the user logs in, set the user entity’s id into a session scoped component. Don’t bother with long running conversations (at least not for the user). The User Home component’s Factory method creates a user component using the session scoped user id, anytime the user component is referenced. This component entity is loaded within the context of the current conversation (if it hasn’t already been loaded). So, presto-magic, no lazy loading issues.

It let me fix the issue with about 20 lines of code, and little trouble. It’s working perfectly so far.

By | 2008-04-11T18:17:40+00:00 April 11th, 2008|Seam|6 Comments

About the Author:

6 Comments

  1. Siarhei April 23, 2008 at 7:12 am - Reply

    Hi Devon,

    I see that you also do ATG. What is your experience in comparing JBoss+Seam with ATG? There is very little info on what exactly ATG is but I also see that ATG is an official partner of JBoss (and that framework from ATG it can run on JBoss as well?). Is it possible to use ATG and JBoss Seam together? Am I even talking any sense here?

    Thanks in advance!

    Siarhei

  2. Devon April 23, 2008 at 3:58 pm - Reply

    Siarhei,

    well ATG has several products which stack on one another. The base layer is somewhat similar to what Seam+Hibernate offers: component lifecycle, configuration, data access, etc…

    The upper layer products provide personalization, commerce, etc… Which obviously Seam doesn’t cover.

    I don’t think it would make sense to try to run the two of them together. The upper layers of ATG products are tightly coupled to the lower ATG framework, and running the two together wouldn’t work too well.

    That said, I think there’s a lot that each framework could learn from the other.

    Devon

  3. Richard January 15, 2010 at 3:02 pm - Reply

    FWIW, we use this pattern extensively and have for a while — however, none of our code extends from EntityHome, which brings a ton of baggage along with it. We just have session-scope ID variables, and a series of conversation-scoped factory methods, similar to that linked to. Basically:

    @In(required = false, value = “currentUserId”)
    private Long id;

    @In
    EntityManager entityManager;

    @Factory(autoCreate = true, scope = ScopeType.CONVERSATION)
    public User getCurrentUser() {
    if (id != null) {
    User user = entityManager.find(User.class, id);
    log.debug(“Returning user {0} for id {1}”, user, id);
    return user;
    }
    return null;
    }

    Trivial and effective. As a bonus, you’re not putting too much information into a long-lived session… which also means that when someone else changes it — say, to remove a user from the system — that data will be reloaded pretty shortly.

    • Devon January 15, 2010 at 6:33 pm - Reply

      Cool. Thanks for sharing it! What is the baggage of EntityHome your’e dodging in particular?

  4. Giorgio September 8, 2010 at 12:48 am - Reply

    Hi devon….i run into this post cuz i’m searching for a general structure for webapp developed with seam….i’m a newbie with it, and with its concepts, but i would like to know if there are any documents, or website i can find useful for this matter….i’ve been working with it since 6 months and i realize it’s a very powerful way to develop webapps which are strongly related to a db…..but i would also like to know how to develop classes, beans and components to have performance, scalability and modularity increased……..any design pattern is welcome, for example one like “u should put objects which are related to views in a session scope, injected instead of a private property of a stateless bean…”….or more, “u should put methods with interactions on the db in a conversation scoped entity, instead of a ejb3 bean…..

    This is cuz i’m seeing performance problems in my apps related to queries and multiple calls (for example when i have a datatable into a page) that made me wondering if i was developing it the right way….

    i don’t know if u get my point…i would like to have something general and high level which tells me how to correctly develop my applications…..hope your experience can help me….and sorry if i’m bothering u =)

    Best Regards….

    • Devon September 8, 2010 at 1:01 pm - Reply

      Giorgio,

      Have you read through all the docs and forums at http://seamframework.org/ ? TONS of useful information. I can attest that Seam can handle massive traffic including database traffic. I’ve written applications that deal with creating and updating tens of millions of records in a database under very high loads and everything hums along very well. I suspect you have code or db config issues that are holding you back.

      Devon

Leave A Comment