0

以下に示すように、2 つのテーブル間に OneToOne の関係があります。

PreRecordLoad.java:

@OneToOne(mappedBy="preRecordLoadId",cascade = CascadeType.ALL)
private PreRecordLoadAux preRecordLoadAux;

PreRecordLoadAux.java:

@JoinColumn(name = "PRE_RECORD_LOAD_ID", referencedColumnName = "PRE_RECORD_LOAD_ID")
@OneToOne
private PreRecordLoad preRecordLoadId;

このメソッドを使用して、PreRecordLoad オブジェクトを引き戻しています。

public PreRecordLoad FindPreRecordLoad(Long ID)
{
    print("Finding " + ID + "f");

    Query query;
    PreRecordLoad result = null;
    try
    {
        query = em.createNamedQuery("PreRecordLoad.findByPreRecordLoadId");
        query.setParameter("preRecordLoadId", ID);
        result = (PreRecordLoad)query.getSingleResult();
        //result = em.find(PreRecordLoad.class, ID);
    }
    catch(Exception e)
    {
        print(e.getLocalizedMessage());
    }

    return result;
}

「+ "f"」は、渡された値の最後に何かが含まれているかどうかを確認するためのものです。そうではありませんでした。

元々 em.find を使用していましたが、どの方法を使用しても同じ問題が発生しました。

ID に BigDecimal を使用していたのは、これがデフォルトだったからです。それが機能する場合と機能しない場合で、精度に違いがあることに気付きました。具体的には、精度は機能しなかったときは 4 でしたが、機能したときは 0 でした。これがなぜなのかわからなかったので、とにかく BigDecimal である必要がなかったので、BigDecimal を Long に変更しました。

新しい PreRecordLoad オブジェクトと PreRecordLoadAux オブジェクトをデータベースに保存し (初めて挿入します)、このメソッドを実行してオブジェクトを呼び戻そうとすると、PreRecordLoad が取得されますが、PreRecordLoadAux は null です。これは、エントリがデータベースにあり、完全にコミットされているように見えるにもかかわらず、別のセッションである SQLDeveloper からアクセスできるためです。

ただし、アプリケーションを停止して再実行すると、両方のオブジェクトが正常にプルバックされます。渡される ID は両方とも同じであるか、少なくとも同じように見えます。

とにかく提案は大歓迎です、ありがとう。

編集:

オブジェクトをDBに永続化するときのコードは次のとおりです。

    if(existingPreAux==null) {
        try {
            preLoad.setAuditSubLoadId(auditLoad);
            em.persist(preLoad);
            print("Pre Record Load entry Created");

            preAux.setPreRecordLoadId(preLoad);
            em.persist(preAux);
            print("Pre Record Load Aux entry Created");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }
    else {
        try {
            preLoad.setPreRecordLoadId(existingPreLoad.getPreRecordLoadId());
            preLoad.setAuditSubLoadId(auditLoad);
            em.merge(preLoad);
            print("Pre Record Load entry found and updated");

            preAux.setPreRecordLoadAuxId(existingPreAux.getPreRecordLoadAuxId());
            preAux.setPreRecordLoadId(preLoad);
            em.merge(preAux);
            print("Pre Record Load Aux entry found and updated");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }

それはメソッド内にあり、そのコードの後、メソッドは終了します。

4

1 に答える 1

1

オブジェクト グラフの一貫性を維持するのは、ユーザーの責任です。だから、あなたがするとき、あなたpreAux.setPreRecordLoadId(preLoad);もしなければなりませんpreLoad.setPreRecordLoadAux(preAux);

そうしないと、同じセッションから をロードするたびにpreAux、最初のレベルのキャッシュから取得されるため、不適切に初期化されたエンティティのインスタンスが返されます。

于 2013-07-16T13:23:49.163 に答える