0

アカウントへの双方向の ManyToOne 関係を持つ Payment エンティティがあります。

@Table(name="account")
public class Account implements Serializable { 

    //bi-directional many-to-one association to Payment
    @OneToMany(mappedBy="account",fetch=FetchType.EAGER)
    private List<Payment> payments;

@Table(name="payment")
public class Payment implements Serializable { 

    //bi-directional many-to-one association to Account
    @ManyToOne(cascade={CascadeType.MERGE},fetch=FetchType.EAGER)
    @JoinColumn(name="idAcc")
    private Account account;

アカウント エンティティは永続化されました。そして、ブラウザとデータベースにそれに関する情報が表示されます。

アカウント [idAcc=475, account=12345678901230, isLock=N, rest=10000.5]

次に、子 (Payment エンティティ) を永続化し、同時に Account エンティティを変更する (アカウントの残りを変更する) 必要があります。私はこのコードを使用します。

    public class GenericDaoImpl<T> implements GenericDao<T> {

        protected Class<T> type; 
        protected EntityManagerFactory emf = null;

        public GenericDaoImpl(Class<T> type, EntityManagerFactory emf) { 
            this.emf = emf;
            this.type = type;       
        } 

        @Override
        public void create(T entity) throws Exception { 
            EntityManager em = null; 
            try { 
                em = getEntityManager();
                em.getTransaction().begin();  
                em.persist(entity); 
                em.getTransaction().commit(); 
            } 
...
@Override
    public T findById(String id) {
         EntityManager em = getEntityManager();
            try {
                Query query = em.createNamedQuery(type.getSimpleName()+".findByName");
                query.setParameter("id", id);
                return (T)query.getSingleResult();
            } finally {
                em.close();
            }
    }

daoPayments = new GenericDaoImpl(Payment.class,factory); 
            Payment payment = null;
                try {
                    payment = new Payment();
                    payment.setDescription("Shop 'Pirasmani'");
                    payment.setSumm(50.25);
                        Account account = (Account)daoAccount.findById(listAccount.get(0).getIdAcc());
                        account.setRest(account.getRest()-payment.getSumm());
                        payment.setAccount(account);
                        account.getPayments().add(payment);

                    daoPayments.create(payment);
                    //print result 
                    Payment paymentMerged = (Payment)daoPayments.read(payment);
                    out.println(paymentMerged.toString()+"<br>"); 

次に、アカウントの残りが変更されたことをブラウザーで確認します。

支払い [idPmnt=91, description=Shop 'Pirasmani', summ=50.25, account=Account [idAcc=475, account=12345678901230, isLock=N, rest=9950.25]]

しかし、データベースでは、アカウントの残りに変更はありません。鋼は=10000.5です。私は何を間違っていますか?ありがとう。

4

1 に答える 1

2

DAOメソッドでトランザクションを開始および停止しないでください。前のセクションのすべてのコードは、単一のトランザクションに含まれている必要があります。これにより、次のことが可能になります。

  • アタッチされたエンティティで作業し、アカウントで行われたすべての変更を自動的に保持します
  • cascade={CascadeType.MERGE}アソシエーションの不要なものを削除します
  • データベースをコヒーレント状態のままにし、現在のように、支払いが作成されたが残りは減らされていない状態ではありません(これが、最初にトランザクションを使用する理由です)。

そうは言っても、あなたは支払いを続けます。なぜそれがアカウントの変更を引き起こすのでしょうか?あなたが持っている唯一のカスケードはMERGEであり、コードでマージを行っていません。

于 2013-03-08T15:39:05.450 に答える