-->
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: Could I remove Hibernate's own implementation of collection?
PostPosted: Mon Sep 26, 2005 11:35 pm 
Newbie

Joined: Mon Sep 26, 2005 11:04 pm
Posts: 1
Location: malaysia
Hibernate Version: 3.1 Beta 3

The situaition is like this:
I'm developing a 3 tier web applications project which the client side are running on the applet.

Basically, Hibernate will replace our own implementation (java Set) with Hibernate's own PersistentSet when we fetch the objects. I have problems with all the persistent objects send to client side as my applet doesn't have dependencies on any Hibernate's API and I wouldn't want to include it in client side because it'll be too heavy. Therefore, I encountered ClassNotFoundException.

Is there anyway to assign a Java collections instead of allowing Hibernate to replace it's own implementations for Collections Mapping? I'm trying to prevent from writing another level of wrapper class to convert all the objects to pure java object because it might affecting the performances.

I found several examples on how this UserCollectionType helps but in Hibernate 3.1 the methods in UserCollectionType are different.

Please consult. Thank you.

[/quote]

_________________
kenji lim chee wooi


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 28, 2005 5:35 am 
Newbie

Joined: Wed Sep 28, 2005 4:07 am
Posts: 11
Here are 2 examples for a UserCollectionType and an Bag-Implementation, that work in Hibernate 3. The classes are called HistoryListType and HistoryListBag.

Note that HistoryListType does not need to implement java.util.List. Because my Entities should not use a Hibernate-dependent class, I have written an Interface "HistoryListIF". Entities only reference this Interface and the real Implementation "HistoryList".

If your Bag implements the java.util.List-Interface you do not need an own Bag-Implementation. Just set the collection-type-Attribute in the <bag>-Tag in in the Mapping-File.

However, your own Bag-Implementation will always have Dependencies to Hibernate. So you will have to put hibernate3.jar on your Client.
If your Client has a Gui, I think its best Practice to give no Entities and no DTOs to the Client. Instead you should give a FormBean to the Client that contains the Strings, that are shown in the Gui. Then you can create a Framework on the Client-Side that fill the GuiComponents with the FormBeans automatically.


[code]
package ba.history.hibernate;

import java.util.*;
import org.hibernate.HibernateException;
import org.hibernate.collection.*;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.usertype.UserCollectionType;

import ba.history.*;
import ba.history.interfaces.*;

public class HistoryListType implements UserCollectionType {

public HistoryListType() {
}

/**
* Optional operation. Does the collection contain the entity instance?
*/
public boolean contains(Object collection, Object obj) {
HistoryListIF historyList = (HistoryListIF)collection;
if( ! (obj instanceof History)) {
return false;
}
return historyList.contains((History)obj);
}

/**
* Return an iterator over the elements of this collection - the passed collection
* instance may or may not be a wrapper
*/
public Iterator getElementsIterator(Object collection) {
return ((HistoryListIF)collection).iterator();
}

/**
* Optional operation. Return the index of the entity in the collection.
*/
public Object indexOf(Object collection, Object obj) {
if( !(obj instanceof History)) {
return new Integer(-1);
}
int index = ((HistoryListIF)collection).indexOf((History)obj);//new Integer(((HistoryList)collection).indexOf(obj));
if(index == -1) {
return null;
}
return new Integer(index);
}
/**
* Instantiate an empty instance of the "underlying" collection (not a wrapper)
*/
public Object instantiate() {
return new HistoryList();
}

/**
* Instantiate an uninitialized instance of the collection wrapper
*/
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException {
// Use hibernate's built in persistent set implementation
//wrapper
return new HistoryListBag(session);
}

/**
* Replace the elements of a collection with the elements of another collection
*/
public void replaceElements(
Object collectionA,
Object collectionB,
CollectionPersister persister,
Object owner,
Map copyCache,
SessionImplementor implementor) throws HibernateException {
HistoryListIF historyListA = (HistoryListIF)collectionA;
HistoryListIF historyListB = (HistoryListIF)collectionB;
historyListB.clear();
int length = historyListA.size();
for (int i = 0; i < length; i++) {
historyListB.add(historyListB.get(i));
}
}

/**
* Wrap an instance of a collection
*/
public PersistentCollection wrap(SessionImplementor session, Object collection) {
// Use hibernate's built in persistent set implementation
//wrapper.
return new HistoryListBag(session, (HistoryList)collection);
}

}



package ba.history.hibernate;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type;
import org.hibernate.collection.*;

import ba.history.*;
import ba.history.interfaces.HistoryListIF;

public class HistoryListBag extends AbstractPersistentCollection implements HistoryListIF {
private HistoryList bag;

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

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

public HistoryListBag(SessionImplementor session, HistoryList historyList) {
super(session);
bag = historyList;
setInitialized();
setDirectlyAccessible(true);
}

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

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

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

public Object readFrom(ResultSet rs, CollectionPersister persister,
CollectionAliases descriptor, Object owner) throws
HibernateException, SQLException {
// note that if we load this collection from a cartesian product
// the multiplicity would be broken ... so use an idbag instead
Object element = persister.readElement(rs, owner,
descriptor.getSuffixedElementAliases(),
getSession());
if (element != null) bag.add( (History) element);
return element;
}

public void beforeInitialize(CollectionPersister persister) {
this.bag = new HistoryList();
}

public boolean equalsSnapshot(CollectionPersister persister) throws
HibernateException {
Type elementType = persister.getElementType();
EntityMode entityMode = getSession().getEntityMode();
java.util.List sn = (java.util.List) getSnapshot();
if (sn.size() != bag.size())return false;
Iterator iter = bag.iterator();
while (iter.hasNext()) {
Object elt = iter.next();
final boolean unequal = countOccurrences(elt, bag.iterator(), elementType,
entityMode) !=
countOccurrences(elt, sn.iterator(), elementType, entityMode);
if (unequal)return false;
}
return true;
}

private int countOccurrences(Object element, Iterator iter, Type elementType,
EntityMode entityMode) throws HibernateException {
int result = 0;
while (iter.hasNext()) {
if (elementType.isSame(element, iter.next(), entityMode)) result++;
}
return result;
}

protected Serializable snapshot(CollectionPersister persister) throws
HibernateException {
EntityMode entityMode = getSession().getEntityMode();
ArrayList clonedList = new ArrayList(bag.size());
Iterator iter = bag.iterator();
while (iter.hasNext()) {
clonedList.add(persister.getElementType().deepCopy(iter.next(),
entityMode, persister.getFactory()));
}
return clonedList;
}

public Collection getOrphans(Serializable snapshot, String entityName) throws
HibernateException {
java.util.List sn = (java.util.List) snapshot;
return getOrphans(sn, bagToCollection(), entityName, getSession());
}

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

private Collection bagToCollection() {
int length = bag.size();
ArrayList erg = new ArrayList();
for (int i = 0; i < length; i++) {
erg.add(bag.get(i));
}
return erg;
}

public Serializable disassemble(CollectionPersister persister) throws
HibernateException {

int length = bag.size();
Serializable[] result = new Serializable[length];
for (int i = 0; i < length; i++) {
result[i] = persister.getElementType().disassemble(bag.get(i), getSession(), null);
}
return result;
}

public void initializeFromCache(CollectionPersister persister,
Serializable disassembled, Object owner) throws
HibernateException {
beforeInitialize(persister);
Serializable[] array = (Serializable[]) disassembled;
for (int i = 0; i < array.length; i++) {
Object element = persister.getElementType().assemble(array[i], getSession(),
owner);
if (element != null) bag.add( (History) element);
}
}

public boolean needsRecreate(CollectionPersister persister) {
return!persister.isOneToMany();
}

// For a one-to-many, a <bag> is not really a bag;
// it is *really* a set, since it can't contain the
// same element twice. It could be considered a bug
// in the mapping dtd that <bag> allows <one-to-many>.

// Anyway, here we implement <set> semantics for a
// <one-to-many> <bag>!

public Iterator getDeletes(CollectionPersister persister,
boolean indexIsFormula) throws HibernateException {
//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
Type elementType = persister.getElementType();
EntityMode entityMode = getSession().getEntityMode();
ArrayList deletes = new ArrayList();
java.util.List sn = (java.util.List) getSnapshot();
Iterator olditer = sn.iterator();
int i = 0;
while (olditer.hasNext()) {
Object old = olditer.next();
Iterator newiter = bag.iterator();
boolean found = false;
if (bag.size() > i && elementType.isSame(old, bag.get(i++), entityMode)) {
//a shortcut if its location didn't change!
found = true;
}
else {
//search for it
//note that this code is incorrect for other than one-to-many
while (newiter.hasNext()) {
if (elementType.isSame(old, newiter.next(), entityMode)) {
found = true;
break;
}
}
}
if (!found) deletes.add(old);
}
return deletes.iterator();
}

public boolean needsInserting(Object entry, int i, Type elemType) throws
HibernateException {
//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
java.util.List sn = (java.util.List) getSnapshot();
final EntityMode entityMode = getSession().getEntityMode();
if (sn.size() > i && elemType.isSame(sn.get(i), entry, entityMode)) {
//a shortcut if its location didn't change!
return false;
}
else {
//search for it
//note that this code is incorrect for other than one-to-many
Iterator olditer = sn.iterator();
while (olditer.hasNext()) {
Object old = olditer.next();
if (elemType.isSame(old, entry, entityMode))return false;
}
return true;
}
}

public boolean isRowUpdatePossible() {
return false;
}

public boolean needsUpdating(Object entry, int i, Type elemType) {
//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
return false;
}

/**
* @see java.util.Collection#size()
*/
public int size() {
read();
return bag.size();
}

/**
* @see java.util.Collection#isEmpty()
*/
public boolean isEmpty() {
read();
return bag.isEmpty();
}

public boolean contains(History history) {
read();
return bag.contains(history);
}

/**
* @see java.util.Collection#iterator()
*/
public Iterator iterator() {
read();
return new IteratorProxy(bag.iterator());
}

/**
* @see java.util.Collection#toArray()
*/
public History[] toArray() {
read();
return bag.toArray();
}

/**
* @see java.util.Collection#add(Object)
*/
public boolean add(History history) {
if (!queueAdd(history)) {
write();
return bag.add(history);
}
else {
return true;
}
}

/**
* Liefert alle Historys, die eine Period haben, die date enthält.
* @param date das Datum
* @return die Historys, die eine Period haben, die date enthält
*/
public HistoryList getValid(Date date) {
read();
return bag.getValid(date);
}

public HistoryList getValid(Period period) {
read();
return bag.getValid(period);
}

public ChangeInfo setAllLimit(Date date) {
write();
return bag.setAllLimit(date);
}

public ChangeInfo minusAll(Period period) {
write();
return bag.minusAll(period);
}


/**
* @see java.util.Collection#remove(Object)
*/
public boolean remove(History history) {
write();
return bag.remove(history);
}

/**
* @see java.util.Collection#containsAll(Collection)
*/
public boolean containsAll(Collection c) {
read();
return bag.containsAll(c);
}

/**
* @see java.util.Collection#addAll(Collection)
*/
public boolean add(Collection c) {
if ( c.size()==0 ) return false;
if ( !queueAddAll(c) ) {
write();
return bag.add(c);
}else {
return c.size()>0;
}
}

/**
* Fügt dieser HistoryList ein Array von Historys hinzu.
* @param histories die Historys
*/
public boolean add(History[] histories) {
return add(Arrays.asList(histories));
}

public void delayedAddAll(Collection c) {
bag.add(c);
}

/**
* @see java.util.Collection#removeAll(Collection)
*/
public boolean remove(Collection c) {
if ( c.size()>0 ) {
write();
return bag.remove(c);
}else {
return false;
}
}

/**
* @see java.util.Collection#clear()
*/
public void clear() {
write();
bag.clear();
}


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

public Object getSnapshotElement(Object entry, int i) {
HistoryList sn = (HistoryList) getSnapshot();
return sn.get(i);
}

public int occurrences(Object o) {
read();
Iterator iter = bag.iterator();
int result=0;
while ( iter.hasNext() ) {
if ( o.equals( iter.next() ) ) result++;
}
return result;
}

// History OPERATIONS:


/**
* @see java.util.List#get(int)
*/
public History get(int i) {
read();
return bag.get(i);
}

/**
* @see java.util.List#indexOf(Object)
*/
public int indexOf(History history) {
read();
return bag.indexOf(history);
}

public String toString() {
read();
return "HistoryListBag: " + bag.toString();
}

/* public boolean equals(Object other) {
read();
return bag.equals(other);
}

public int hashCode(Object other) {
read();
return bag.hashCode();
}*/

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

/**
* Bag does not respect the collection API and do an
* JVM instance comparison to do the equals.
* The semantic is broken not to have to initialize a
* collection for a simple equals() operation.
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
return super.equals(obj);
}

/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return super.hashCode();
}


///////////////////////////////////////////////////////////////////////////////////
// PRIVATE KLASSEN
///////////////////////////////////////////////////////////////////////////////////
final class IteratorProxy implements Iterator {
private final Iterator iter;
IteratorProxy(Iterator iter) {
this.iter=iter;
}
public boolean hasNext() {
return iter.hasNext();
}

public Object next() {
return iter.next();
}

public void remove() {
write();
iter.remove();
}

}

}

_________________
Lars Fiedler


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.