alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (PersistentIdentifierBag.java)

This example Hibernate source code file (PersistentIdentifierBag.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

arraylist, hashmap, hibernateexception, hibernateexception, integer, integer, io, iterator, jdbc, list, map, map, object, object, persistentidentifierbag, serializable, sql, util

The Hibernate PersistentIdentifierBag.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008-2011, 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.collection.internal;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type;

/**
 * An <tt>IdentifierBag implements "bag" semantics more efficiently than
 * a regular <tt>Bag by adding a synthetic identifier column to the
 * table. This identifier is unique for all rows in the table, allowing very
 * efficient updates and deletes. The value of the identifier is never exposed
 * to the application.<br>
 * <br>
 * <tt>IdentifierBags may not be used for a many-to-one association.
 * Furthermore, there is no reason to use <tt>inverse="true".
 *
 * @author Gavin King
 */
public class PersistentIdentifierBag extends AbstractPersistentCollection implements List {

	protected List values; //element
	protected Map identifiers; //index -> id

	public PersistentIdentifierBag(SessionImplementor session) {
		super(session);
	}

	public PersistentIdentifierBag() {} //needed for SOAP libraries, etc

	public PersistentIdentifierBag(SessionImplementor session, Collection coll) {
		super(session);
		if (coll instanceof List) {
			values = (List) coll;
		}
		else {
			values = new ArrayList();
			Iterator iter = coll.iterator();
			while ( iter.hasNext() ) {
				values.add( iter.next() );
			}
		}
		setInitialized();
		setDirectlyAccessible(true);
		identifiers = new HashMap();
	}

	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
	throws HibernateException {
		Serializable[] array = (Serializable[]) disassembled;
		int size = array.length;
		beforeInitialize( persister, size );
		for ( int i = 0; i < size; i+=2 ) {
			identifiers.put(
				new Integer(i/2),
				persister.getIdentifierType().assemble( array[i], getSession(), owner )
			);
			values.add( persister.getElementType().assemble( array[i+1], getSession(), owner ) );
		}
	}

	public Object getIdentifier(Object entry, int i) {
		return identifiers.get( new Integer(i) );
	}

	public boolean isWrapper(Object collection) {
		return values==collection;
	}

	public boolean add(Object o) {
		write();
		values.add(o);
		return true;
	}

	public void clear() {
		initialize( true );
		if ( ! values.isEmpty() || ! identifiers.isEmpty() ) {
			values.clear();
			identifiers.clear();
			dirty();
		}
	}

	public boolean contains(Object o) {
		read();
		return values.contains(o);
	}

	public boolean containsAll(Collection c) {
		read();
		return values.containsAll(c);
	}

	public boolean isEmpty() {
		return readSize() ? getCachedSize()==0 : values.isEmpty();
	}

	public Iterator iterator() {
		read();
		return new IteratorProxy( values.iterator() );
	}

	public boolean remove(Object o) {
		initialize( true );
		int index = values.indexOf(o);
		if (index>=0) {
			beforeRemove(index);
			values.remove(index);
			dirty();
			return true;
		}
		else {
			return false;
		}
	}

	public boolean removeAll(Collection c) {
		if ( c.size() > 0 ) {
			boolean result = false;
			Iterator iter = c.iterator();
			while ( iter.hasNext() ) {
				if ( remove( iter.next() ) ) result=true;
			}
			return result;
		}
		else {
			return false;
		}
	}

	public boolean retainAll(Collection c) {
		initialize( true );
		if ( values.retainAll( c ) ) {
			dirty();
			return true;
		}
		else {
			return false;
		}
	}

	public int size() {
		return readSize() ? getCachedSize() : values.size();
	}

	public Object[] toArray() {
		read();
		return values.toArray();
	}

	public Object[] toArray(Object[] a) {
		read();
		return values.toArray(a);
	}

	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
		identifiers = anticipatedSize <= 0 ? new HashMap() : new HashMap( anticipatedSize + 1 + (int)( anticipatedSize * .75f ), .75f );
		values = anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize );
	}

	public Serializable disassemble(CollectionPersister persister)
			throws HibernateException {
		Serializable[] result = new Serializable[ values.size() * 2 ];
		int i=0;
		for (int j=0; j< values.size(); j++) {
			Object value = values.get(j);
			result[i++] = persister.getIdentifierType().disassemble( identifiers.get( new Integer(j) ), getSession(), null );
			result[i++] = persister.getElementType().disassemble( value, getSession(), null );
		}
		return result;
	}

	public boolean empty() {
		return values.isEmpty();
	}

	public Iterator entries(CollectionPersister persister) {
		return values.iterator();
	}

	public boolean entryExists(Object entry, int i) {
		return entry!=null;
	}

	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
		Type elementType = persister.getElementType();
		Map snap = (Map) getSnapshot();
		if ( snap.size()!= values.size() ) return false;
		for ( int i=0; i<values.size(); i++ ) {
			Object value = values.get(i);
			Object id = identifiers.get( new Integer(i) );
			if (id==null) return false;
			Object old = snap.get(id);
			if ( elementType.isDirty( old, value, getSession() ) ) return false;
		}
		return true;
	}

	public boolean isSnapshotEmpty(Serializable snapshot) {
		return ( (Map) snapshot ).isEmpty();
	}

	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
		Map snap = (Map) getSnapshot();
		List deletes = new ArrayList( snap.keySet() );
		for ( int i=0; i<values.size(); i++ ) {
			if ( values.get(i)!=null ) deletes.remove( identifiers.get( new Integer(i) ) );
		}
		return deletes.iterator();
	}

	public Object getIndex(Object entry, int i, CollectionPersister persister) {
		throw new UnsupportedOperationException("Bags don't have indexes");
	}

	public Object getElement(Object entry) {
		return entry;
	}

	public Object getSnapshotElement(Object entry, int i) {
		Map snap = (Map) getSnapshot();
		Object id = identifiers.get( new Integer(i) );
		return snap.get(id);
	}

	public boolean needsInserting(Object entry, int i, Type elemType)
		throws HibernateException {

		Map snap = (Map) getSnapshot();
		Object id = identifiers.get( new Integer(i) );
		return entry!=null && ( id==null || snap.get(id)==null );
	}

	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {

		if (entry==null) return false;
		Map snap = (Map) getSnapshot();
		Object id = identifiers.get( new Integer(i) );
		if (id==null) return false;
		Object old = snap.get(id);
		return old!=null && elemType.isDirty( old, entry, getSession() );
	}


	public Object readFrom(
		ResultSet rs,
		CollectionPersister persister,
		CollectionAliases descriptor,
		Object owner)
		throws HibernateException, SQLException {

		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
		Object old = identifiers.put(
			new Integer( values.size() ),
			persister.readIdentifier( rs, descriptor.getSuffixedIdentifierAlias(), getSession() )
		);
		if ( old==null ) values.add(element); //maintain correct duplication if loaded in a cartesian product
		return element;
	}

	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
		HashMap map = new HashMap( values.size() );
		Iterator iter = values.iterator();
		int i=0;
		while ( iter.hasNext() ) {
			Object value = iter.next();
			map.put(
				identifiers.get( new Integer(i++) ),
				persister.getElementType().deepCopy(value, persister.getFactory())
			);
		}
		return map;
	}

	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
		Map sn = (Map) snapshot;
		return getOrphans( sn.values(), values, entityName, getSession() );
	}

	public void preInsert(CollectionPersister persister) throws HibernateException {
		Iterator iter = values.iterator();
		int i=0;
		while ( iter.hasNext() ) {
			Object entry = iter.next();
			Integer loc = new Integer(i++);
			if ( !identifiers.containsKey(loc) ) { //TODO: native ids
				Serializable id = persister.getIdentifierGenerator().generate( getSession(), entry );
				identifiers.put(loc, id);
			}
		}
	}

	public void add(int index, Object element) {
		write();
		beforeAdd(index);
		values.add(index, element);
	}

	public boolean addAll(int index, Collection c) {
		if ( c.size() > 0 ) {
			Iterator iter = c.iterator();
			while ( iter.hasNext() ) {
				add( index++, iter.next() );
			}
			return true;
		}
		else {
			return false;
		}
	}

	public Object get(int index) {
		read();
		return values.get(index);
	}

	public int indexOf(Object o) {
		read();
		return values.indexOf(o);
	}

	public int lastIndexOf(Object o) {
		read();
		return values.lastIndexOf(o);
	}

	public ListIterator listIterator() {
		read();
		return new ListIteratorProxy( values.listIterator() );
	}

	public ListIterator listIterator(int index) {
		read();
		return new ListIteratorProxy( values.listIterator(index) );
	}

	private void beforeRemove(int index) {
		Object removedId = identifiers.get( new Integer(index) );
		int last = values.size()-1;
		for ( int i=index; i<last; i++ ) {
			Object id = identifiers.get( new Integer(i+1) );
	        if ( id==null ) {
				identifiers.remove( new Integer(i) );
	        }
	        else {
				identifiers.put( new Integer(i), id );
	        }
		}
		identifiers.put( new Integer(last), removedId );
	}

	private void beforeAdd(int index) {
		for ( int i=index; i<values.size(); i++ ) {
			identifiers.put( new Integer(i+1), identifiers.get( new Integer(i) ) );
		}
		identifiers.remove( new Integer(index) );
	}

	public Object remove(int index) {
		write();
		beforeRemove(index);
		return values.remove(index);
	}

	public Object set(int index, Object element) {
		write();
		return values.set(index, element);
	}

	public List subList(int fromIndex, int toIndex) {
		read();
		return new ListProxy( values.subList(fromIndex, toIndex) );
	}

	public boolean addAll(Collection c) {
		if ( c.size()> 0 ) {
			write();
			return values.addAll(c);
		}
		else {
			return false;
		}
	}

	public void afterRowInsert(
		CollectionPersister persister,
		Object entry,
		int i)
		throws HibernateException {
		//TODO: if we are using identity columns, fetch the identifier
	}

}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate PersistentIdentifierBag.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.