问题
Lets suppose we have some entity, which has 10 fields. And let's suppose that almost all these fields have very large data. And we want to load entity (not the set of fields!) and at runtime define which fields to load. The solution I found https://stackoverflow.com/a/24710759/5057736 suggests using constructor. But in case of 10 fields and that it is necessary to define fields at runtime is not possible solution. Is there a way how to solve this problem using jpa 2.1?
回答1:
Use a JPA 2.1 EntityGraph to define the fields to be retrieved by the query. So if you have a class MyClass
, and want to retrieve particular fields dynamically, something like this could suffice
EntityGraph<MyClass> eg = em.createEntityGraph(MyClass.class);
eg.addAttributeNodes("id");
eg.addAttributeNodes("name");
eg.addAttributeNodes("relation");
Query q = em.createQuery("SELECT b FROM MyClass b");
q.setHint("javax.persistence.fetchgraph", eg);
List<MyClass> results = q.getResultList();
回答2:
With a Hibernate session this can be gained through using a result transformer. Hibernate doesn't support the result transformers for JPA.
HHH-8196 Custom ResultTransformer for JPA criteria queries
You can use unwrap(Session.class)
to apply a result transformer to the session.
List<Person> persons = entityManager.unwrap(Session.class).
createQuery("select name as name from Person").
setResultTransformer(
Transformers.aliasToBean(Person.class)
).list();
Additional information about nested projections
回答3:
The Fetch graphs are mostly targeted to fetching associations, not for individual fields.
Even if the JPA spec says that fields should be lazy by default, LAZY is just a hint for the JPA providers, which might choose to ignore it. Hibernate does not use lazy loading for fields by default. Only one-to-many and many-to-many associations are LAZY by default.
To have lazy fields, you need to enable bytecode enhancement and maybe use @LazyGroup as well.
Anyway, maybe a DTO projection query is what you needed in the first place.
来源:https://stackoverflow.com/questions/37049358/hibernate-load-entities-with-fields-defined-at-runtime