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.
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.