I am implanting Hibernate in a very big project and that is in development since 2001. After a lot of work, we have a problem to map our collections to hibernate. We don't use Java Collections Types directly, we have a class (named RepositorioIteravelCollection) that isn't a subclass of any Java Collections Type, but contains a private Java Collection Type (ArrayList) and a private iterator. We access these classes throught various methods and we don't need to take care about construct news iterators and how this iterator access the collection. Each object in the project has his own collection, so we don't need to take about casts when we access the RepositorioIteravelCollection's.
The problem is that we couldn't map this to hibernate. I don't think that make RepositorioIteravelCollection implements UserTypeCollection will work, because RepositorioIteravelCollection is not a collection, but contains a collection, so the instantiate and wrap methods won't work. I thought in make a map for each RepositorioIteravelCollection, but I would have to make a reference to these maps in many-to-many or one-to-many associations, and I think that it isn't possible.
Does anyone could help me?
This is an exemple of RepositorioIteravelCollection code (look that there is an interface above it):
public final class RepositorioMenusIteravelCollection implements
RepositorioMenusIteravel, UserCollectionType {
Collection menus;
Iterator iterator;
//from UserTypeCollection
public RepositorioMenusIteravelCollection(){
}
/**
* Constructor
*/
public RepositorioMenusIteravelCollection (Collection menus){
this.menus = menus;
this.iterator = menus.iterator();
}
//from UserTypeCollection
public boolean contains(Object collection, Object obj) {
Collection colecao = (Collection)collection;
return colecao.contains(obj);
}
//from UserTypeCollection
public Iterator getElementsIterator(Object collection) {
return ((Collection)collection).iterator();
}
//from UserTypeCollection
public Object indexOf(Object collection, Object obj) {
return null;
}
//from UserTypeCollection
public void replaceElements(
Object collectionA,
Object collectionB,
CollectionPersister persister,
Object owner,
Map copyCache,
SessionImplementor implementor) throws HibernateException {
Set setA = (Set)collectionA;
Set setB = (Set)collectionB;
setB.clear();
setB.addAll(setA);
}
//from UserTypeCollection
// factory method for certain collection type.
public Object instantiate() {
return new RepositorioMenusIteravelCollection(new ArrayList());
}
//from UserTypeCollection
// standard wrapper for collection type.
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException {
// Use hibernate's built in persistent set implementation
//wrapper
return new PersistentBag(session);
}
//from UserTypeCollection
// standard wrapper for collection type.
public PersistentCollection wrap(SessionImplementor session, Object colllection) {
// Use hibernate's built in persistent set implementation
//wrapper.
return new PersistentBag(session, ((RepositorioMenusIteravelCollection)colllection).getCollection());
}
/**
* Add a collection of menus
*
* @return void
*
*/
public final void adicionar(Collection novaColecao) {
this.menus.addAll(novaColecao);
this.iterator = menus.iterator();
}
/**
* Return the next menu in the sequence
*/
public final Menu proximo() {
return (Menu) iterator.next();
}
/**
* Return if exists a next menu in the sequence
*/
public final boolean temProximo() {
return iterator.hasNext();
}
/**
* Return the size of the collection
*/
public final int tamanho() {
return menus.size();
}
/**
* Init another iterator
*/
public final void reiniciar() {
iterator = menus.iterator();
}
/**
* Return the collection of the repositorio
*/
public final Collection getCollection(){
return this.menus;
}
/**
* order menus for description
*
*/
public void ordenarPorDescricao() {
ArrayList lista = new ArrayList(menus);
Collections.sort(lista,new ComparadorPorDescricao());
menus = lista;
reiniciar();
}
}
And a map that uses this class:
<?xml version="1.0" encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="siga.controleAcesso.modulo">
<class name="Modulo" table="SIGA_MODULO" lazy="false" >
<id name="codigo" column="CD_MODL" >
<generator class="sequence">
<param name="sequence">SQ_CD_MODL</param>
</generator>
</id>
<timestamp name="timestamp" column="TS_MODL" />
<property name="descricao" column="DS_MODL"/>
<bag name="colecaoMenusIteravel" table="SIGA_MODL_MENU" lazy="true" collection-type="siga.controleAcesso.menu.RepositorioMenusIteravelCollection">
<key column="CD_MODL"/>
<many-to-many class="siga.controleAcesso.menu.Menu" column="CD_MENU"/>
</bag>
</class>
</hibernate-mapping>
and the class Modulo:
public final class Modulo extends ObjetoSiga implements ParChaveValor {
private int codigo;
private String descricao;
private RepositorioMenusIteravel colecaoMenusIteravel;
public Modulo() {
}
/**
*
* @param codigo
* @param descricao
* @param colecaoMenusIteravel
*/
public Modulo(int codigo,String descricao, RepositorioMenusIteravel colecaoMenusIteravel){
this.codigo = codigo;
this.descricao = descricao;
this.colecaoMenusIteravel = colecaoMenusIteravel;
}
/**
*
* @param codigo
* @param descricao
* @param timestamp
* @param colecaoMenusIteravel
*/
public Modulo(int codigo, String descricao,Timestamp timestamp, RepositorioMenusIteravel colecaoMenusIteravel){
super(timestamp);
this.codigo = codigo;
this.descricao = descricao;
this.colecaoMenusIteravel = colecaoMenusIteravel;
}
/**
*
* @return
*/
public final int getCodigo(){
return codigo;
}
/**
*
* @param codigo
*/
public final void setCodigo(int codigo){
this.codigo = codigo;
}
/**
*
* @return
*/
public final String getDescricao(){
return descricao;
}
/**
*
* @param descricao
*/
public final void setDescricao(String descricao){
this.descricao = descricao;
}
/**
*
* @return
*/
public final RepositorioMenusIteravel getColecaoMenusIteravel(){
return colecaoMenusIteravel;
}
/**
*
* @param colecaoMenusIteravel
*/
public final void setColecaoMenusIteravel(RepositorioMenusIteravel colecaoMenusIteravel){
this.colecaoMenusIteravel = colecaoMenusIteravel;
}
}
When I try to run, a PropertyAccessException occurs in setColecaoMenusIteravel, caused by a ClassCastException.
|