0
我有支付實體雙向ManyToOne releshionship帳戶。JPA如何堅持雙向ManyToOne父母
@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,帳戶= 123456789,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,說明=店 'Pirasmani',SUMM = 50.25, account = Account [idAcc = 475,account = 123456789,isLock = N, rest = 9950.25]]
但是在數據庫中賬戶休息沒有變化。鋼= 10000.5。 我在做什麼錯?謝謝。
感謝您的快速響應。爲什麼我不應該在DAO方法中啓動和停止事務?我在JPA的例子中發現了DAO的標準代碼。所以我爲所有實體使用一個通用的DAO.class。而且,據我所知,JPA註釋使用這個通用的DAO爲我打了個洞。我認爲我的註釋有問題。有沒有其他方式如何解決我的問題,而無需更改DAO或我需要爲每個實體編寫特定的DAO? – Foontik 2013-03-08 16:03:17
因爲交易的重點是保證ACIDity(原子性,連貫性,隔離性,耐久性)。您希望您的數據保持一致:或者創建了付款,其餘的數據都減少了,或者這兩個操作都沒有完成。這就是交易被使用的原因。如果每個操作都是在單個事務中完成的,那麼您的數據庫不會保持一致狀態(正如您剛剛看到的那樣)。事務應該由服務層劃分,而不是由DAO層劃分。 – 2013-03-08 16:06:56
好的,謝謝,我明白了,但如果我在服務層中移動了交易,我的老師不會很高興。我知道什麼是ACID。我曾經想過,如果我改變第一個實體和第二個實體(由Cascade註釋映射)比堅持第一個實體,所以這會自動改變其他實體的單個事務。這不是JPA的主要特性嗎?而且我知道它的效果很好,例如,如果您創建父項並添加他的新子項,那麼對於「OneToMany」,只需堅持父項。在這種情況下,不需要編碼Cascade註釋。全部存儲在單個事務中。 – Foontik 2013-03-08 17:12:39