/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.event.internal; import java.io.Serializable; import org.jboss.logging.Logger; import org.hibernate.engine.internal.Versioning; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.LockMode; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.Status; import org.hibernate.event.spi.AbstractEvent; import org.hibernate.event.spi.EventSource; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; import org.hibernate.type.TypeHelper; /** * A convenience base class for listeners that respond to requests to reassociate an entity * to a session ( such as through lock() or update() ). * * @author Gavin King */ public class AbstractReassociateEventListener implements Serializable { private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractReassociateEventListener.class.getName()); /** * Associates a given entity (either transient or associated with another session) to * the given session. * * @param event The event triggering the re-association * @param object The entity to be associated * @param id The id of the entity. * @param persister The entity's persister instance. * * @return An EntityEntry representing the entity within this session. */ protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) { if (LOG.isTraceEnabled()) LOG.trace("Reassociating transient instance: " + MessageHelper.infoString(persister, id, event.getSession().getFactory())); final EventSource source = event.getSession(); final EntityKey key = source.generateEntityKey( id, persister ); source.getPersistenceContext().checkUniqueness( key, object ); //get a snapshot Object[] values = persister.getPropertyValues( object ); TypeHelper.deepCopy( values, persister.getPropertyTypes(), persister.getPropertyUpdateability(), values, source ); Object version = Versioning.getVersion( values, persister ); EntityEntry newEntry = source.getPersistenceContext().addEntity( object, ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ), values, key, version, LockMode.NONE, true, persister, false, true //will be ignored, using the existing Entry instead ); new OnLockVisitor( source, id, object ).process( object, persister ); persister.afterReassociate( object, source ); return newEntry; } }