hypersistence-utils icon indicating copy to clipboard operation
hypersistence-utils copied to clipboard

isCollectionType returns false for ListArrayType

Open hsinyin opened this issue 3 years ago • 4 comments

ListArrayType is a grant child of AbstractStandardBasicType which sets isCollectionType to false.

The impact is When using CriteriaBuilder with the field it checks if attributeMetadata.isPlural() by reading isCollectionType. The field should be ListAttribute but since it is not a collection type it was builded as a SingularAttribute.

And calling CriteriaBuilder.isMember() throws unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]

Code example:

A Entity

@TypeDef(name = "list-array", typeClass = ListArrayType.class)
public class AEntity implements Serializable {
  ID and other fields..

  @Type(type = "list-array")
  @Column(name = "version", columnDefinition = "integer[]", nullable = false)
  private List<Integer> version;
}

Queries

final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<AEntity> cq = cb.createQuery(AEntity.class);
final Root<AEntity> root = cq.from(AEntity.class);

cq.select(root).where(cb.isMember(filter.getVersion(0), root.get("version")));
entityManager.createQuery(cq).getResultList();

hsinyin avatar Dec 17 '21 00:12 hsinyin

Hibernate Types doesn't generate the Metamodel. Hibernate does that. So, this issue is a Hibernate problem.

Therefore, you need to open thr issue on the Hibernate project and provide a fix there.

vladmihalcea avatar Dec 17 '21 04:12 vladmihalcea

ListArrayType should overwrite isCollectionType to true. Or extend a different class like CollectionType instead.

hsinyin avatar Dec 17 '21 18:12 hsinyin

Send me a Pull Request with this fix plus a replicating test case and I'll check it out.

vladmihalcea avatar Dec 17 '21 19:12 vladmihalcea

For anyone facing this, a temporary workaround can be to integrated a direct DB function.

Example with above use case, on PostgreSQL: cb.isNotNull(cb.function("array_position", Integer.class, filter.getVersion(0), root.get("version")))

nmandrescu avatar Feb 17 '22 16:02 nmandrescu