01: //$Id: DefaultLockEventListener.java 7019 2005-06-05 05:09:58Z oneovthafew $
02: package org.hibernate.event.def;
03:
04: import java.io.Serializable;
05:
06: import org.hibernate.HibernateException;
07: import org.hibernate.LockMode;
08: import org.hibernate.TransientObjectException;
09: import org.hibernate.engine.Cascade;
10: import org.hibernate.engine.CascadingAction;
11: import org.hibernate.engine.EntityEntry;
12: import org.hibernate.engine.ForeignKeys;
13: import org.hibernate.event.EventSource;
14: import org.hibernate.event.LockEvent;
15: import org.hibernate.event.LockEventListener;
16: import org.hibernate.engine.SessionImplementor;
17: import org.hibernate.persister.entity.EntityPersister;
18:
19: /**
20: * Defines the default lock event listeners used by hibernate to lock entities
21: * in response to generated lock events.
22: *
23: * @author Steve Ebersole
24: */
25: public class DefaultLockEventListener extends
26: AbstractLockUpgradeEventListener implements LockEventListener {
27:
28: /** Handle the given lock event.
29: *
30: * @param event The lock event to be handled.
31: * @throws HibernateException
32: */
33: public void onLock(LockEvent event) throws HibernateException {
34:
35: if (event.getObject() == null) {
36: throw new NullPointerException("attempted to lock null");
37: }
38:
39: if (event.getLockMode() == LockMode.WRITE) {
40: throw new HibernateException("Invalid lock mode for lock()");
41: }
42:
43: SessionImplementor source = event.getSession();
44:
45: Object entity = source.getPersistenceContext()
46: .unproxyAndReassociate(event.getObject());
47: //TODO: if object was an uninitialized proxy, this is inefficient,
48: // resulting in two SQL selects
49:
50: EntityEntry entry = source.getPersistenceContext().getEntry(
51: entity);
52: if (entry == null) {
53: final EntityPersister persister = source
54: .getEntityPersister(event.getEntityName(), entity);
55: final Serializable id = persister.getIdentifier(entity,
56: source.getEntityMode());
57: if (!ForeignKeys.isNotTransient(event.getEntityName(),
58: entity, Boolean.FALSE, source)) {
59: throw new TransientObjectException(
60: "cannot lock an unsaved transient instance: "
61: + persister.getEntityName());
62: }
63:
64: entry = reassociate(event, entity, id, persister);
65:
66: cascadeOnLock(event, persister, entity);
67: }
68:
69: upgradeLock(entity, entry, event.getLockMode(), source);
70: }
71:
72: private void cascadeOnLock(LockEvent event,
73: EntityPersister persister, Object entity) {
74: EventSource source = event.getSession();
75: source.getPersistenceContext().incrementCascadeLevel();
76: try {
77: new Cascade(CascadingAction.LOCK, Cascade.AFTER_LOCK,
78: source).cascade(persister, entity, event
79: .getLockMode());
80: } finally {
81: source.getPersistenceContext().decrementCascadeLevel();
82: }
83: }
84:
85: }
|