0

EJB メソッドがあります。

    public List<Rfsprsus> findAll() {
    List<Rfsprsus> rl = getEntityManager()
            .createNamedQuery("Rfsprsus.findAll", Rfsprsus.class)
            .getResultList();

    for(Rfsprsus r: rl) {
        StringBuilder tempPwd = new StringBuilder("");
        for(int i = 0; i < paramFacade.find().getPwlength(); i++) {
            tempPwd.append("a");
        }
        r.setPassword(tempPwd.toString());
        if(r.getOrg() == null) r.setOrg(orgFacade.find("011"));         }
    return rl;

しかし、このメソッドを呼び出した後、データベースをチェックします。for ループが実際に更新を引き起こしたことに非常に驚いています。

理由も方法もわからないので教えてください!

4

4 に答える 4

1

これをメソッドの上に追加しました。

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

魔法のように働きました!

于 2012-10-10T07:12:14.460 に答える
0

アクティブなトランザクション内にある添付エンティティを処理しているためだと思います。

つまり、エンティティ マネージャによって引き続き管理されます。エンティティ マネージャによって管理され、進行中のトランザクションの一部であるエンティティは、データベースへのライブ リンクのように機能します。トランザクションを開始する場合、データベースからデータを取得し、たとえばセッターを使用してオブジェクト データを変更し、トランザクションを閉じてデータベースを更新します。これらの場合、persist または merge コマンドは必要ありません。

データベースから返されたデータを操作するが、データベースを更新しない場合は、エンティティを切り離すか、DTO (データ転送オブジェクト) を使用します。つまり、トランザクションの範囲外でデータを変更したり、エンティティ マネージャーによって管理されていないオブジェクトにデータを転送したりします。

于 2012-10-10T07:10:03.917 に答える
0

更新は次の行の間で発生する可能性があります。

r.setPassword(tempPwd.toString()); 
if(r.getOrg() == null) r.setOrg(orgFacade.find("011"));

rまず、メモリ内のエンティティを更新しています。何が原因かわかりませんorgFacade.find()が、DB にクエリを実行していると思います。JPA は、クエリを実行する前に、保留中の変更を DB にフラッシュします。これは、クエリが既に更新されたオブジェクトに「触れる」場合に備えてrです (すべてが 1 つのトランザクションで実行されることに注意してください)。したがって、の副作用としてDBでパスワードが更新されると思いますorgFacade.find()。解決策は単純かもしれません。前述の行の順序を変更するだけです。

if(r.getOrg() == null) r.setOrg(orgFacade.find("011"));
r.setPassword(tempPwd.toString()); 
于 2012-10-10T07:26:11.163 に答える