繁体   English   中英

JPA如何在双向ManyToOne中坚持父级

[英]JPA how to persist parent in bi-directional ManyToOne

我有支付实体,双向ManyToOne releshionship帐户。

@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,休息= 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。 我究竟做错了什么? 谢谢。

您不应该在DAO方法中启动和停止事务。 最后一节中的所有代码都应该在一个事务中,这将允许您

  • 处理附加的实体,并自动保留对帐户所做的所有更改
  • 删除关联上不必要的cascade={CascadeType.MERGE}
  • 使数据库保持连贯状态,而不是像现在一样,处于已创建支付但其余部分尚未减少的状态(这就是我们首先使用交易的原因)。

也就是说,你坚持付款。 为什么会导致其帐户的任何修改? 您拥有的唯一级联是MERGE,并且您没有在代码中进行任何合并。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM