1

しばらく問題なく使用している Hibernate エンティティがあります。状態変数を使用して (問題なく動作する) メソッドを保護するためのコードをいくつか追加し、別のトランザクションで状態を設定およびクリアしました。これにより、同じクラスのローカル プライベート変数にアクセスするメソッドで問題が発生しました。以前はこれらの変数に直接アクセスできましたが、現在は get メソッドを使用して変数を取得する必要があります。そうしないと、それらの変数のアンロードされた値を取得します。

以下は、機能した最初のコードです

  • 取引を開く
  • Hibernate を介してオブジェクトをフェッチする
  • メソッドを呼び出す (doTheWork())
  • プライベート変数を参照する
  • 初期化された値ではなく、変数の保存された値が表示されます (1)

        public class Desktop
        {
            public static void main()
        {
            String tx = createTransaction();
            Desktop desktop = getDesktop(tx);
            desktop.doTheWork();
            commitTransaction(tx);
        }
    
        private static Desktop getDesktop(String tx)
        {
            return (Desktop)txFactory.getSession(tx).load(Desktop.class, 5L);
        }
        Long nextVersion = new Long(1);
    
    public Long getNextVersion()
    {
        return nextVersion;
    }
    
    public void doTheWork()
    {
        Log.info("Value of nextVersion is " + nextVersion);
    }
    

    }

以下は変更されたコードです

  • トランザクションを開いてオブジェクトをフェッチする
  • メソッドを呼び出す
  • 別のトランザクションで状態変数を設定する
  • 別のトランザクションを開き、新しいトランザクションでこのオブジェクトのコピーを取得します
  • (本質的に)同じメソッドを呼び出す(doTheWorkImpl())
  • 永続化された変数ではなく、初期化された変数 (1) の値が表示されるようになりました。

    パブリック クラス デスクトップ

    public static void main()
    {
        String tx = createTransaction();  // Hibernate transaction
        Desktop desktop = getDesktop(tx);  // Fetch object using Hibernate
        desktop.doTheWork();
        commitTransaction(tx);
    }
    

    ロング nextVersion = 新しいロング (1);

    public Long getNextVersion()
    {
        return nextVersion;
    }
    
    private void doTheWork()
    {
        String tx = createTransaction();
        setState(State.BUSY);
        commitTransaction(tx);
    
        tx = createTransaction();
        Desktop desktop = getDesktop(tx);
        desktop.doTheWorkImpl();
        commitTransaction(tx);
    
        tx = createTransaction();
        setState(State.NORMAL);
        commitTransaction(tx);
    }
    
    private void doTheWorkImpl()
    {
        Log.info("Value of nextVersion is " + nextVersion);
    }
    

    }

変数への直接参照を変更して getNextVersion() を呼び出すと、正しい値が表示されます。

Hibernate がプロキシを使用することは理解していますが、以前はこのコードが機能していた理由がわかりません。現在、プロキシのロードを強制する必要があります。基本的に同じように動作する Hibernate オブジェクトが多数ある (Hibernate を介してロードされた後に変数を直接参照する) ため、ここで紹介したパターンを変更するものを理解したいと思います。

ここで、session.load() ではなく session.get() を使用することを提案する回答を見ましたが、上記のコードのように常に load を使用してきました。

4

0 に答える 0