0

我有与帐户具有双向多对一关系的付款实体。

@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, 账户=12345678901230, isLock=N, rest=10000.5]

然后我需要坚持孩子(支付实体)并同时更改帐户实体(更改帐户休息)。我使用此代码。

    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 回答