2012-01-27 2 views
0

これは私に何年もの間迷惑をかけましたが、jpaのリファレンスやこのサイトでは何も見つかりません。エンティティが計算されたメンバ(Inverse via mappedby、@Formula、...)を持つ場合、その計算されたメンバのトランザクション的に一貫した更新を得る方法はないようです。そのパターンは、片側の設定者が消費者を知り、現場でそれを更新する必要があるようです。私は何かを欠いているに違いない。うまくいけば、以下は十分に例示的なものです。JPAはトランザクションの一貫性のある方法で逆のフィールドをリフレッシュ

元のフェッチからのものが同期していない場合に備えて、計算されたメンバーをobjで再度em.getReferenceまたは.findを呼び出さなければならないという要件があったとしても大丈夫です。フィールドの更新がない場合と全く同じインスタンスを返します。

import java.util.Set; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.EntityManager; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.ManyToOne; 
import javax.persistence.OneToMany; 
import javax.persistence.PersistenceContext; 

import org.springframework.transaction.annotation.Transactional; 

@Entity 
public class InverseProblemDto { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 
    @OneToMany(mappedBy="problem") 
    public Set<OwnerDto> owners; 

    public int otherField = 0; 
} 

@Entity 
public class OwnerDto { 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private int id; 

    @ManyToOne 
    public InverseProblemDto problem; 

    public int yetAnotherField = 0; 
} 


@Transactional 
public void wontWork(int dbId) { 
    @PersistenceContext 
    EntityManager em; 

    InverseProblemDto probDto = em.find(InverseProblemDto.class, dbId); 
    probDto.otherField++; 

    for (OwnerDto other : probDto.owners) { 
     // do something 
    } 

    OwnerDto newOwner = new OwnerDto(); 
    newOwner.problem = probDto; 
    em.persist(newOwner); 

    // do more 

    // How to ensure this finds newOwner w/o breaking transactional integrity by forcing a flush and refresh??? 
    for (OwnerDto other : probDto.owners) { 
     if (other.id == newOwner.id) System.out.println("Yeah! found it"); 
    } 

} 

答えて

1

フラッシュとリフレッシュはトランザクションをコミットしませんが、保留中のSQLのみをデータベースに発行します。

あなたは常にこのよう値を自分で変更することができます:

@Entity 
public class InverseProblemDto { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 
    @OneToMany(mappedBy="problem") 
    public Set<OwnerDto> owners; 

    public int otherField = 0; 

    public void addOwner(OwnerDto owner) { 
     ... 
    } 
} 

@Entity 
    public class OwnerDto { 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private int id; 

    @ManyToOne 
    public InverseProblemDto problem; 

    public int yetAnotherField = 0; 

    public void setProblem(InverseProblemDto problem) { 
     if(problem != null) { 
      problem.addOwners(this); 
     } 
     this.problem = problem; 
    } 

}

+0

おかげで、それはトランザクション一貫とどまることを思い出させるために。それは役に立ちます。 – DHM

関連する問題