Hibernate Simulated Persistence:持久性和提交之间有什么可能?

Hibernate Simulated Persistence: What is possible between persistence and commit?

我目前正在为混合来源的对象编写模拟上下文。其中一些对象是从数据库加载的持久性休眠实体。其他是临时创建的新 'simulated' 对象,稍后可能会存储在数据库中。

本应用程序处理有向图,这些图是使用 Hibernate 实体从数据库加载的。目前它只是检查循环子结构。映射是这样安排的,它从数据库中延迟加载 NodesEdges。这允许我的循环检查器根据存储在直接相关 Edges.

中的信息通过延迟获取相邻 Nodes 来遍历整个图
Node {
    Integer id; // mapped id
    List<Edge> edges; // mapped and fetched lazy
}

Edge {
    Integer id; // mapped id
    Integer predecessorId; // mapped
    Integer successorId; // mapped
    Node predecessor; // mapped and fetched lazy
    Node successor; // mapped and fetched lazy
}

现在我想在图中添加一条边,而不将其存储在数据库中。无论如何,CycleChecker 应该首先 运行,但要考虑到优势。我想知道我是否可以重用现有的 CycleChecker 并完全使用 Hibernate 实体解决该问题,而不必为 "simulated" 实体编写额外的代码。

两个问题:

  1. 如果我创建一个新的 Edge 并将其持久保存在 Hibernate Session 中(比如受事务上下文限制),我是否能够延迟加载其 Node commit() 之前来自数据库的后继者?

  2. 如果我创建一个新的 Node 并将其保存在会话中(没有提交或刷新发生),Hibernate 会通过 get(Id) 或从另一个新的延迟加载找到它Edge?

如果这一切都不可能,是否有一种 Hibernate 方法可以连接到提取中,以便从我的模拟上下文中 return 对象?

当我们使用与 Hibernate 实体一起工作的算法(并依赖于 Hibernate 延迟加载关系)时,我不久前制定了这个解决方案。模拟启动事务并持久化所有对象以进行模拟。所有模拟对象都必须首先从缓存中逐出,否则延迟关系加载将无法工作。计算完成后,可以停止模拟,即回滚事务。详情见我的代码:

public class SimulationContext {

    private Session session = null;
    private Transaction transaction = null;

    private List<Simulateable> simulatedObjects;

    public SimulationContext() {
        this.simulatedObjects = new ArrayList<Simulateable>();
    }

    /** ... add, remove, clear, ... */

    /**
     * Start simulation: Start transaction and persist simulation entities.
     * @param session
     */
    public void start(Session session) {
        if (this.session != null) {
            this.stop();
        }
        this.session = session;
        this.transaction = session.beginTransaction();

        // Initializing simlation context, persisting simulated objects
        for (Simulateable object : simulatedObjects) {
            // persist object ...
            session.persist(object);
            session.flush();
            // ... and remove it from session cache (otherwise lazy loaded objects referenced by foreign keys might not get loaded)
            session.evict(object);
        }
    }

    /**
     * Stop simulation: Roll-back the transaction and close the session.
     */
    public void stop() {
        transaction.rollback();
        transaction = null;
        session = null;
    }
}