An efficient way to initialize a list of Hibernate proxies linked to different objects


#1

I have a number of JPA classes containing fields of a certain type in various combinations. This looks like this:

// entity to initialize
@Entity
class Type {
  ...

  @ManyToOne(fetch = LAZY)
  B b;
}

// containers

@Entity
class A {
  ...

  @ManyToOne(fetch = LAZY)
  Type type;
}

@Entity 
public class B {
  ...

  @ManyToOne
  C c;

  @OneToMany(fetch = LAZY)
  List<Type> possibleTypes;
}

@Entity
public class C {
  ...

  @OneToMany
  List<B> b;

  @OneToOne(fetch = LAZY)
  Type type;
}

Is there a way to initialize all Type proxies with one SELECT without building a manual request or initializing fields one by one with a number of Hibernate.initialize() calls? Something like

Set<Type> possibleProxies = new HashSet<>();
possibleProxies.add(a1.getType());
for (B b : c1.getB()) {
  possibleProxies.addAll(b.getPossibleTypes());
}
possibleProxies.add(c1.getType());
initializeAll(possibleProxies);

so that Hibernate or related library would check if some of the objects are already initialized and build a correct SELECT query according to JPA mapping.


#2

There is no such feature. This is because you rarely want to traverse all associations and ending up fetching the entire database with a single method call.

You could JOIN FETCH the to-one associations and a to-many association as well. For the other associations, you could use a Reflection-based tool to trigger the initialization, although this might not be desirable.

If your goal is to transform the entities to DTOs, better fetch them as DTOs using a ResultTransformer.


#3

Thanks for the answer!
I suppose I’ll have to implement this feature manually.
JOIN FETCH or ResultTransformer is not an option here because I have to perform the initial request to DB and proxy initialization (required for mapping to DTO) in 2 separate services divided by a massive business logic layer which may filter out 90% of the selected entities…