aspose file tools*
The moose likes JSF and the fly likes Represent Inheritance of Domain model in JSF Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Represent Inheritance of Domain model in JSF" Watch "Represent Inheritance of Domain model in JSF" New topic
Author

Represent Inheritance of Domain model in JSF

Stuart L Smith
Greenhorn

Joined: Feb 25, 2009
Posts: 3
I have been looking for the answer to a question but have yet to find it so I figure I'll post before I'm up all night (hate not solving problems)...

With Hibernate or JPA we have lots of options for modeling inheritance within the domain model. We can have a base class that holds shared properties and sub-classes for unique properties.

I've been struggling with a good way to represent this in JSF and reusing the Java classes already designed for the domain layer.

As example (with pseudo-code simplifications):

class Payment {
id;
date;
amount;
}

class CreaditPayment extends Payment {
creditCardNumber;
}

class CheckingPayment extends Payment {
bankRouting;
}

With Hibernate/JPA we can represent this by using an inheritance strategy that stores what the actual "type" of the domain object is in a discriminator column. The problem that will pop up later is this is like a "pseudo property" since it is not actually in any of the Java classes (no get/set). This column exists in the database to tell Hibernate/JPA which type of object instance to create in the object model.

The problem in JSF appears when I try to display these different elements in something like a table. I'd like to use a single table to show all "payments" and simply have columns filled in if the payment instance has that type of property. This means there will be JSF tags like this:
<h: outputText value=#{payment.creditCardNumber}"/>
<h: outputText value=#{payment.bankRouting}"/>

The problem is when I try this I get JspPropertyNotFoundException which of course makes perfect sense because the instances won't have the Java properties of the other sub-class.

I need some way to conditionaly evaluate the expression based on the type of instance or tell JSF to skip this altogether. Unfortunately, since the 'type' is not an actual Java property I'm not sure how to do this.

I won't consider creating a DTO class that has all possible properties because that is just a hack that doesn't deserve recognition. There are sub-classes for a reason.

There could be something extremely simple that I'm missing here. If that is the case I will truly be glad to say "how could I be so dumb?" after the problem is solved.

I think part of the problem is that since WebSphere and JBoss only recently came out with Java EE 5 implementations we have not as an industry really explored the question "How do we update our design patterns to account for the new technologies (JSF, JPA, EJB 3)?". Hopefully questions like this can help us do that (and give a Google hit to the next poor sap that is trying to solve this problem at 5AM )

Thanks,
Stuart Smith
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

JSF can interact directly with domain objects, but as often as not, it ends up less than ideal, Thanks to annoying little things like trying to glue boolean checkboxes to domain object that map databases that don't have native boolean types, I usually seem to end up creating a fa├žade or decorator as a go-between. And, of course since no domain object has any business containing business logic, it's not uncommon for me to present the actual domain object as a property off the backing bean that supports the business logic.

Then there's the dreaded OptimisticLockingException. JSF tends to push me to use more session objects than I'd like, and I've learned that in JDO and JSP if I store a bean in a session object, I have to detach it and then re-merge it. Except that re-merging doesn't always work.

The biggest obstacle to your problem, however, is that you don't define backing beans as interfaces, you have do define a discrete, instantianable class so that the framework can construct them as needed with zero external knowledge.

J2EE design patterns are not identical to the more general GOF design patterns, and JSF has its own constraints. It may be annoying not to be able to use a one-pattern-fits-all approach, but it is nevertheless possible to apply method to the madness.


Customer surveys are for companies who didn't pay proper attention to begin with.
Stuart L Smith
Greenhorn

Joined: Feb 25, 2009
Posts: 3
I was presenting the domain objects as a property of a managed bean.

At first I was trying to come up with a table to list all current data as the best place to start. Once I started thinking about how to create new records this leads me back to a class in the view layer to represent all possible properties and then using utility classes to convert that to the domain object upon form submission.

If I was not going back to having a separate class this would be possible by altering the Hibernate mapping to expose the property being used as the discriminator column also as a regular Java property.

The insert="false" is required to prevent Hibernate from trying to update the same column twice. I found this as a solution presented for the problem where you might have to change the type of the sub-class and therefore need to alter the value of the discriminator column. This would be important to preserve relationships that are linked to the existing key value.

I could then use this property as a test for the 'rendered' property of JSF components to avoid evaluating EL expressions for properties that don't exist.

I have two outputText so that the cell is filled in with alternate text for the properties of the other sub-class that don't apply for this instance.

The issue for adding new data is that every form field needs to be associated with a property. I had a suggestion from another team member about a way to dynamically change the type of sub-class associated with the managed bean property for the payment and only display the properties for the current type.





You could probably also use a third party AJAX library or the improved AJAX support of JSF 2.0 to do this. I think it is certain that perhaps we can create more simple yet powerful applications by leveraging the inheritance available in the domain layer, using the domain class objects directly in the view to avoid duplication, and dynamic forms that can present only the types of fields required for a specific sub-class.

Thanks,
Stuart

PS. If you're looking for a solution to a problem like this and get a Google hit on this be thankful that perhaps we are starting to explore more powerful applications like this and perhaps you can get some sleep I wasn't able to.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

Polymorphic domain objects are not something I routinely deal with. Usually, I'm handed an existing RDBMS and have to take it from there.

However, conditional property expression has other uses besides polymorphic objects.

I recommend you look at Facelets components.
Stuart L Smith
Greenhorn

Joined: Feb 25, 2009
Posts: 3
I'm definitely going to start looking at Facelets more now that it will be more integrated with JSF 2.0.

JSF seemed left out of the simplification theme in Java EE 5 simply because this was the first time it was required as part of Java EE. It will be good to see that JSF will also get a "tune-up" starting with Java EE 6.

This is not your boss' J2EE...

Stuart
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

I've been using Facelets for a year or 2 now. There are 2 major reasons:

1. Unlike Tiles, I find that I can define tiled pages in a way that both makes sense and isn't more trouble than it's worth.

2. Facelets intercepts JSF errors and reports them in a more useful way than straight JSF does.

Somewhat in line with the original topic of this thread - I am working on a project which, while not polymorphic, has 4 different views of the same object type. So I made a Facelets component out of the view, parameterized it for the different object instances, and invoked the component 4 times.

In your particular advantage, I'd probably do something similar and do conditional rendering on the component. For one thing, with my typing skills, I'd never manage to get all those item-level "rendered" attributes spelled correctly!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Represent Inheritance of Domain model in JSF