01: /*
02: * Copyright 2002-2007 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.springframework.orm.hibernate3.support;
18:
19: import java.io.Serializable;
20: import java.util.Map;
21:
22: import org.hibernate.engine.SessionImplementor;
23: import org.hibernate.event.MergeEvent;
24: import org.hibernate.event.def.DefaultMergeEventListener;
25: import org.hibernate.persister.entity.EntityPersister;
26:
27: /**
28: * Extension of Hibernate's DefaultMergeEventListener, transferring the ids
29: * of newly saved objects to the corresponding original objects (that are part
30: * of the detached object graph passed into the <code>merge</code> method).
31: *
32: * <p>Transferring newly assigned ids to the original graph allows for continuing
33: * to use the original object graph, despite merged copies being registered with
34: * the current Hibernate Session. This is particularly useful for web applications
35: * that might want to store an object graph and then render it in a web view,
36: * with links that include the id of certain (potentially newly saved) objects.
37: *
38: * <p>The merge behavior given by this MergeEventListener is nearly identical
39: * to TopLink's merge behavior. See PetClinic for an example, which relies on
40: * ids being available for newly saved objects: the <code>HibernateClinic</code>
41: * and <code>TopLinkClinic</code> DAO implementations both use straight merge
42: * calls, with the Hibernate SessionFactory configuration specifying an
43: * <code>IdTransferringMergeEventListener</code>.
44: *
45: * <p>Typically specified as entry for LocalSessionFactoryBean's "eventListeners"
46: * map, with key "merge".
47: *
48: * @author Juergen Hoeller
49: * @since 1.2
50: * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setEventListeners(java.util.Map)
51: */
52: public class IdTransferringMergeEventListener extends
53: DefaultMergeEventListener {
54:
55: /**
56: * Hibernate 3.1 implementation of ID transferral.
57: */
58: protected void entityIsTransient(MergeEvent event, Map copyCache) {
59: super .entityIsTransient(event, copyCache);
60: SessionImplementor session = event.getSession();
61: EntityPersister persister = session.getEntityPersister(event
62: .getEntityName(), event.getEntity());
63: // Extract id from merged copy (which is currently registered with Session).
64: Serializable id = persister.getIdentifier(event.getResult(),
65: session.getEntityMode());
66: // Set id on original object (which remains detached).
67: persister.setIdentifier(event.getOriginal(), id, session
68: .getEntityMode());
69: }
70:
71: }
|