1
votes

I'm trying to retrieve all data from a table in an MsSQL database using Hibernate 5.2.11.Final and using java reflection to get the value of a field in each row. This seems to be troublesome for Hibernate/JPA.

The layout

  • Class A is abstract, single table type. Has string variable named "x"
  • Class B inherits from A

How I exact the data

Field field = null;
try {
    field = A.class.getDeclaredField("x");
    field.setAccessible(true);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

CriteriaQuery<A> query = criteriaBuilder.createQuery(A.class);
Root<A> root = query.from(A.class);
query.select(root);
ScrollableResults results = session.createQuery(query).setFetchSize(100).scroll(ScrollMode.FORWARD_ONLY);

while (results.next()) {
    Object entity = results.get(0);
    log.info(entity.getClass().getSimpleName() + " " + field.get(entity))
}

This prints out:

B test
B test2
B test3
B_$$_jvst26f_48c null
B test5

What is B_$$_jvst26f_48c? If I apply "entity instanceof A" it returns true - yet I cannot extract its value using reflection. If I cast the entity-object to class A and extract the value using .getX() then there's no issue.

1

1 Answers

2
votes

B_$$_jvst26f_48c is a proxy class generated by Hibernate to help lazy loading.

For instance assume some entity has a reference to a B, however that B might never be accessed so it might not be necessary to load it.

That proxy class will override the methods of B and add a test checking if the instance was loaded, i.e. something like (this is pseudocode):

@Override
public int getX() {
    if (!proxyIsLoaded) {
        loadProxy();
    }
    return super.get();
}

This way you can transparently call getX() you don't need to know it's proxy.

However as you have seen, accessing the fields through reflection does not work.

You can add the @Proxy(lazy = false) annotation to the class but this will disable a lot of lazy loading cases for this entity