Java Persistence with Hibernate 展示了许多如何急切获取关联实体的示例,例如:
- 将@org.hibernate.annotations.BatchSize 添加到关联的类
- 将@org.hibernate.annotations.Fetch 添加到引用关联类的字段中
- 在 HQL 查询等中使用“fetch”关键字...
但是,在我的情况下,我正在处理一个运行缓慢的过程,该过程负责建立与感兴趣的实体类的关联。这意味着 - 在执行时 - 我不能查询一个实体并要求它急切地获取另一个实体的所有关联实例,因为不存在这样的关联。
换句话说,这个过程看起来像这样:
public class InitConfig {
private final SessionFactory sessionFactory;
private final NodeManager nodeManager;
public void run() {
final Configuration config = new Configuration("NewConfiguration", new HashSet<Node> ());
for(String name : lotsOfNames) {
//Lots of these queries run slowly
final Node node = this.nodeManager.getNode(name);
config.addNode(node);
}
this.sessionFactory.getCurrentSession().save(config);
}
}
相关的 DAO (NodeManager) 和慢查询实体 (Node) 如下所示:
public class NodeManager {
private final SessionFactory sessionFactory;
public Node getNode(String name) {
final Session db = this.sessionFactory.getCurrentSession();
final Query query = db.createQuery("from NODE where NAME = :name");
query.setString("name", name);
return (Node)query.uniqueResult();
}
}
@Entity(name="NODE")
public class Node {
@GeneratedValue(strategy=GenerationType.TABLE)
@Id @Column(name="ID")
private Long id;
private @Column(name="NAME", nullable=false, unique=true) String name;
//Other properties and associations...
}
最后,由缓慢运行的进程创建的实体:
@Entity(name="CONFIGURATION")
public class Configuration {
@Id @GeneratedValue @Column(name="ID")
private Long id;
private @Column(name="NAME", nullable=false, unique=true) String name;
@ManyToMany
@JoinTable(
name="CONFIGURATION_NODE",
joinColumns=@JoinColumn(name="CONFIGURATION_ID", nullable=false),
inverseJoinColumns=@JoinColumn(name="NODE_ID", nullable=false))
private Set<Node> nodes = new HashSet<Node> ();
public void addNode(Node node) {
this.nodes.add(node);
}
}
我的问题是:如何修改 Hibernate 配置和/或代码以一次急切地获取多个 Node 实例?
后续问题将是:
- Hibernate 的 2 级缓存是否适合于此,如果适合 - 我该如何配置它?
- 如果没有,这里是否可以使用其他一些 Hibernate 功能?
目前大约有 100,000 个节点,所以我不愿意采取蛮力的方法来查询每个节点并将其缓存在应用程序的某个地方,因为这不会扩展到更多的节点并且看起来会重复应用程序和 Hibernate 内部(会话、二级缓存等)之间的数据。