Search code examples
javahibernatehibernate-mappinghibernate-criteria

hibernate: Many to Many relationship with View and table


I am trying to query between a view and a table, using hibernate.

I prepare 3 projections, something like SELECT id, name, storages

hibernate entities are

@Entity
@Table(name = "cl_libraryWithItems_view")
public class LibraryWithItemsViewModel implements Serializable {
    .... other columns

@ManyToMany(fetch = FetchType.EAGER)
    @ForeignKey(name = "fk_library_id", inverseName = "fk_storage_id")
    @JoinTable(name = "cl_library_storage",
            joinColumns = {@JoinColumn(name="library_id")},
            inverseJoinColumns = {@JoinColumn(name="storage_id")})
    Set<StorageModel> storages = new HashSet<StorageModel>();

second entity (i'm only including the relevant columns)

@Entity
@Table(name = "cl_storage")
public class StorageModel implements Serializable {
@ManyToMany(mappedBy = "storages")
    private final Set<LibraryModel> libraries = new HashSet<LibraryModel>();
}

I get an ArrayIndexOutOfBoundsException. I looked under the hood, and it appears that error is thrown in the following spot.

In SimpleProjection.java, line 90, number of columns for storage column is 0. For first two columns, I get 1.

int numColumns =  getColumnCount( criteria, criteriaQuery );

in same file, elsewhere,

public int getColumnCount(Criteria criteria, CriteriaQuery criteriaQuery) {
        Type types[] = getTypes( criteria, criteriaQuery );
        int count = 0;
        for ( int i=0; i<types.length; i++ ) {
            count += types[ i ].getColumnSpan( criteriaQuery.getFactory() );
        }
        return count;
    }

This messes up line 164 in CriteriaLoader (out of bounds is thrown here)

result[i] = types[i].nullSafeGet(rs, columnAliases[pos], session, null);

An additional detail, in CollectionType.java the getColumnSpan returns 0. Since we are expecting collection, this method gets triggered, and returns 0.

public int getColumnSpan(Mapping session) throws MappingException {
    return 0;
}

So the problem appears to be that, our column a collection, and getColumnSpan returns 0.

Now the question is how to fix it. What do I need to do, so I can successfully project the storages column?

Thanks.


Solution

  • I was doing something really silly.

    I wanted to do a bi-directional mapping, but what I was doing was not bi-directional.

    LibraryWithItemsViewModel had a set of StorageModel. StorageModel needs to have a set of LibraryWithItemsViewModel as well.

    This problem goes away with this change. More dragons lurk ... but a tale for another day.