Home Hibernate miss existing field
Reply: 1

Hibernate miss existing field

B. Pleshakov
B. Pleshakov Published in 2017-12-07 12:57:24Z

I have such entity structure

public abstract class Base {
    UUID id;

public abstract class Parent<C extends Child> extends Base {
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<C> children;

public abstract class Child<P extends Parent> extends Base {
    @JoinColumn(name = "parent_id", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private P parent;

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "ap")
public class AP extends Parent<AC> {}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "ac")
public class AC extends Child<AP> {}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "bp")
public class BP extends Parent<BC> {}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "bc")
public class BC extends Child<BP> {}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "cp")
public class CP extends Parent<CC> {}

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "cc")
public class CC extends Child<CP> {
     String value;

I do criteria query

    CriteriaQuery<Long> cq = getEntityManager().getCriteriaBuilder().createQuery(Long.class);
    Root<CP> rt = cq.from(CP.class);
    Path child = rt.join("children");
    final CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
    cq.where(criteriaBuilder.equal(child.get("value"), "exists"));
    TypedQuery<Long> q = getEntityManager().createQuery(cq);
    Long res = q.getSingleResult()

and get error on line with where clause:

java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [value] on this ManagedType [Base]

After debugging a while I've found out that Parent meta class in entity manager's meta model keeps property children as List of AC. AC obviously doesn't contains field "value".

Any idea how to fix this error?

pirho Reply to 2017-12-07 15:47:06Z

I think there is no easy fix. Unless you are willing to move value to AC and make CC to extend AC<CP>. Or something alike.

This behavior is because of type erasure.

The actual generic type of children is not available at runtime because compiler casts list to generic type List<AC> based on the upper bound AC.

See also this great answer that explained this thing to me quite well.

After query it is possible to check and cast the list / items to actual type but not at all sure if it is possible within CriteriaQuery.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.303275 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO