-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 23 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How can I ensure that business rules are applied ?
PostPosted: Fri Dec 30, 2005 12:12 pm 
Newbie

Joined: Mon Nov 15, 2004 6:47 am
Posts: 8
Location: Paris, France
Hi,

I work in the R&D department of a large software editor (>4000 people). We are thinking of moving to an ORM like Hibernate and fairly soon to EJB 3.0 persistence (maybe Hibernate EntityManager).

One of the most important considerations that we have is to protect our database. Even more than most companies, this data is vital. It is what we sell.

I have a certain number of architectural questions / problems that seem to be inherent to an entity-based approach to persistence and would be very grateful for your opinions J

Here goes…

My application is split into layers. There is a DAO layer, a business/service layer (with several sub-layers), an application layer (equivalent to a struts action) and a Rich Client (Flex) layer. The architecture is two tiered; the DAO, service and application layers are on the same machine.

We use Spring to achieve loose coupling between application layers and to facilitate unit testing.

In an ideal world…

We would like to be able to lazy-load right up to the application layer.
We would like to ensure that any entities that are committed have passed all validations in the business layer.

The Issue…

We cannot control the database commit to ensure that our business rules have been applied. The business layer may be by-passed and we can do nothing to prevent this.

An example…

If we want lazy-loading from the start, the session must be opened in the application layer. We could use the open-session-in-view pattern to achieve this.

Now imagine that we want to modify two entities, A and B. The application layer makes a call to the service layer and two persistent entities are returned. Both are modified then a transactional method is called that will take A and check its business rules before performing a commit in the database (an important point here is that the transaction is on a service/business layer method). Everything goes OK and the transaction terminates.

The result is that modifications to both A and B have been committed to the database… The problem, of course, is that the modifications to B have not been verified by the business layer.

As a partial solution to this problem I can see that one might change transactional boundaries or the boundaries of the Hibernate session but none of these solutions can assure that my business rules have been applied before a commit.

If you got this far…

I would very much like to have your opinions on this as it seems to me that this is an important issue but is a subject that has not received much attention.

Many thanks for any replies !

Chris White


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 30, 2005 12:49 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Consider JBoss Seam http://www.jboss.com/products/seam and it's Hibernate Validator use.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 30, 2005 1:16 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Database constraints ensure this stuff (and probably nothing else can ensure it).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 30, 2005 2:29 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Hibernate Validator does that. It express the constraints at the DB level if you use Hibernate DLL generation, it checks the *same* constraints before inserting/updating entities, it can also check your constraints at your service level if you call HV, finally, if you use JBoss Seam the *same* constraints are applied at the presentation level through JSF

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 30, 2005 2:51 pm 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
In Hibernate In Action pp. 311-320, and other places, it is recommended that you explicitly retrieve the data subset you want for a particular use case. So when you retrieve A and B, modify them and send them back, that submit request will go to a service that *knows* it will get an A and a B and can validate them both.

Like you, we thought that Hibernate would make persistence "transparent" not only within the server process, but across tiers in our system (which has rich clients), but have found otherwise. Because the burden of getting and sumitting the right data by explicitly walking it is placed on the client tier, you may not hit the problem where unknown subgraphs of objects move to the client and are modified and sent back to be stored; rather you may find that each service method or Command object fully understands the extent of the (non-proxied) data that is moving between tiers.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 31, 2005 3:06 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Just keep constraints in database if data is important.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 6:21 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Hibernate Validator can ensure that since it express the DB constraints on the DDL when DDL is generated by Hibernate, plus you can check the *same* constraints just before insert/update time, you can also apply them anytime you want through an instance of Hibernate Validator (ie in your business logic)
Finally, if you use JBoss Seam, the *same* constraints will be applied at the presentation layer through JSF

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 10:25 am 
Newbie

Joined: Mon Nov 15, 2004 6:47 am
Posts: 8
Location: Paris, France
Hi, thanks for the replies.

As Emmanuel suggested, I could use the Hibernate Validator to check constraints. The check could be made at the service level. However, how can I be sure that my service has been called?

I can see one solution:

1 Add a flag to an entity that indicates whether or not business rules have been validated.

2 Use the EntityManager @pre-update callback annotation to verify before a flush that this flag returns true. If not, the callback method triggers a runtime exception.

This implies that I call a “set” method on an object only after checking business rules (can anyone confirm that this is a best-practice?)

What do you think?

Thanks,

Chris White


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 10:34 am 
Newbie

Joined: Mon Nov 15, 2004 6:47 am
Posts: 8
Location: Paris, France
oops,

When i say

"This implies that I call a “set” method on an object only after checking business rules (can anyone confirm that this is a best-practice?) "

I am talking about a "set" method being called on a persistent object

Sorry for any confusion

Chris White


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 10:47 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
ChrisWhite wrote:
The check could be made at the service level. However, how can I be sure that my service has been called?

use the hibernate validator event listeners. Check the ref doc in Hibernate Annotations for more info. The check will be done as part of the Hibernate event listener

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 02, 2006 11:17 am 
Newbie

Joined: Mon Nov 15, 2004 6:47 am
Posts: 8
Location: Paris, France
Thanks Emmanuel,

Can you confirm that best practice is to check business rules before “setting” a property on a persistent object?

Thus, it is possible to verify that business rules have been called before the flush event (using the event listener)


Thanks,

Chris White


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2006 6:06 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
IMO,
The best place to ensure integrity is the DB itself as Baliukas said.

Otherwise, it depends of what you mean by before setting a property. If you mean before executing setMyProperty() then it's going to be hard to test complex rules involving several properties.

The HibernateValidator events check the business rules during the flush event, before each insert/update.
There is no safe way to check the rules "before" a flush start in hibernate. Such a possibility would duplicate a lot of the flush mechanism.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2006 7:27 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
It is common to have external programs/scripts to update/load data, constraints help to maintain this stuff in single place and it is "safe". Database error messages are not user friendly and it makes sence to use validation tools to solve this problem in UI level (it is more UI usability feature than validation).
It makes sence to check paramter values if your service method doe's something with paramters, but it doe's not make sence to validate persistent state in application level, database doe's it for you.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2006 9:43 am 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
I've been following this thread from a *business rule* perspective, but it seems the replies are about DB integrity.

E.g. how can you validate that a Customer account balance is non-negative when the Customer is saved with a new Transaction added to the Customer's Account object?

Particularly if the CustomerService does not have business rules for account management because they are in the AccountService, but the Account and Transactions are persistable from a Customer object (via cascade settings).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2006 10:07 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
"CHECK( $balance > 0)", "$balance" can be a query,function call or field. This stuff performs better than client side validation too. Triggers can be used for more complex stuff.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 23 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.