-->
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.  [ 2 posts ] 
Author Message
 Post subject: Enforcing rules with hibernate
PostPosted: Fri Sep 08, 2006 6:18 am 
Newbie

Joined: Thu Jul 28, 2005 8:27 am
Posts: 2
I have a program which manages reservations for events. I use two tables, Event, which holds the name of the event and the maximum number of available tickets, and Reservation, which is associated with an Event and keeps track of a number of tickets to be reserved for a specific person.

Below a simplified version of these classes:

Code:
public class Event {
  private String nameOfEvent;
  private int maxTickets;
}


Code:
public class Reservation {
  private Event event;
  private String nameOfUser;
  private int desiredTickets;
}


I have a business rule which states that the number of tickets reserved for a particular Event should never exceed the maxTickets value for that Event.

To enforce this rule I use the following code (heavily simplified):

Code:
private void save(Session session, Event event) {
  Transaction transaction = session.beginTransaction();

  Object[] result = (Object[])session.createQuery("SELECT count(*) FROM Reservation r WHERE r.event = :event").setParameter("event", event).uniqueResult();

  if(((Integer)result[0]) > event.getMaxTickets()) {
    transaction.rollback();
    throw new RuntimeException("Amount exceeded!");
  }

  event.saveOrUpdate(event);
 
  transaction.commit();
}


This code will work 99% of the time, however it fails when a Reservation was altered (and committed) by someone else just after I did the query that checks the business rule. I can easily reproduce it by putting a 10 second delay after the createQuery line.

All the records I use have versions. What I expected to happen was that all of the records queried in the count query would be read locked (since I'm inside a transaction) to guarantee they cannot be changed while I do calculations with the data, which may or may not result in a real change.

However what happens is that Hibernate only checks if the main record was altered (the Event record) and does not read lock the records in my count query at all.

What would be the best way to solve this problem? I've been looking into using a higher transaction level (Serializable), manually locking the relevant records in the Reservation table, or obtaining an exclusive lock on the associated Event for any changes that relate to that Event.

I'm pretty sure this must have been solved before, so what solution would you recommend?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 08, 2006 7:45 pm 
Senior
Senior

Joined: Sat Nov 27, 2004 4:13 am
Posts: 137
You can add a "reservedTickets" to event. On inserting a new reservation increase it and on deletion decrease it.

_________________
don't forget to credit!

Amir Pashazadeh
Payeshgaran MT
پايشگران مديريت طرح
http://www.payeshgaran.co
http://www.payeshgaran.org
http://www.payeshgaran.net


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

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.