Jakarta ee OptMisticLocking内部字段异常
我有一个Person类,它是各种其他交易的一部分,例如销售或付款。我有这个人类链接到支付和销售以及没有级联。所以,当我想坚持销售,也有付款。我这样做 OBS:我有SalesBean、PaymentBean、PersonBean 1-Sales Bean首先尝试持续付款。Jakarta ee OptMisticLocking内部字段异常,jakarta-ee,jpa,jpa-2.0,Jakarta Ee,Jpa,Jpa 2.0,我有一个Person类,它是各种其他交易的一部分,例如销售或付款。我有这个人类链接到支付和销售以及没有级联。所以,当我想坚持销售,也有付款。我这样做 OBS:我有SalesBean、PaymentBean、PersonBean 1-Sales Bean首先尝试持续付款。 2-SalesBean调用PaymentBean.persistPayment()来持久化付款。 在PaymentBean.persistPayment()内部,调用PersonBean以在persistPerson()返回时持
2-SalesBean调用PaymentBean.persistPayment()来持久化付款。
在PaymentBean.persistPayment()内部,调用PersonBean以在persistPerson()返回时持久化分配回支付的人员。并且付款被持久化并返回给SalesBean。
3-在SalesBean中,它获取返回的付款,获取现有客户,分配回销售实体并尝试将其持久化。
此时,我收到OptmisticLockingException,抱怨客户内部的电话自上次读取以来已被更改、删除等。我不认为这是真的,因为我处于开发的早期阶段,我从单元测试用例调用这个方法 OBS: 1-所有实体从一个抽象实体继承版本字段 注意:我后来尝试使用SalesBean的实体管理器执行refresh(),但我得到一个EntityNotFoundException,甚至首先使用EntityManager.contains()进行检查
公共类Person扩展抽象性{
静态私有最终长serialVersionUID=201111151919L;
@Id@GeneratedValue
私人长id;
...
@可接合(name=“个人电话”)
@多个(级联=级联类型.ALL)
专用电话;
公共电话扩展了抽象性{
静态私有最终长serialVersionUID=201111151918L;
@嵌入ID
私人电话号码;
...
@ManyToMany(mappedBy=“telephones”,fetch=FetchType.LAZY)
私人业主;
if(saleEntity.getOwner()!=null&&saleEntity.getOwner().getId()0){
em.merge(销售实体);
//将付款支付给销售,直到付款。。。
}否则{//没有足够的未申请付款来支付
BigDecimal unpaidDifference=saleEntity.getBalance().getAmount().subtract(可用的CreditToPay);
如果(saleEntity.getOwner().getCreditLimit()!=null&&saleEntity.getOwner().getCreditLimit().getAmount()!=null&&saleEntity.getOwner().getCreditLimit().getAmount().floatValue()>=unpaidDifference.floatValue()){//客户有信用额度
em.merge(销售实体);
}否则{//客户没有信用额度
if(saleEntity.getCoSigner()==null?false:(saleEntity.getCoSigner().getCreditLimit().getAmount().floatValue()>=unpaidDifference.floatValue()){
em.merge(销售实体);
}
}
}
**********************************
第一块代码在合并之前执行。我尝试检查客户是否已经被持久化。如果没有,我尝试将其持久化。有时客户在此处被持久化,但大多数时间在之前通过类似的调用被持久化,如“paymentManager.persistCreditTransaction(currentPmt);”这将保留来自该客户的任何付款(如果有),从而保留此人并将其分配回saleEntity我猜您正在从同一原始对象多次合并同一对象 i、 e
- 您将获得版本为1的对象
- 合并它(提交的版本现在是2,但本地副本的版本仍然是1)
- 您再次调用merge,并得到一个锁错误,因为您正在尝试提交旧数据
您需要在每次合并后更新本地副本,方法是在每次提交后或每次事务开始时返回提交的对象。向我们显示导致异常的代码以及异常的堆栈跟踪。旁注:您不希望在多个电话上使用cascade=ALL:删除时,它将尝试删除一个人的所有电话一个人,虽然这些电话被其他人使用。您好,我添加了您要求的代码。感谢您提供有关cascade=ALL的提示。我没有使用cascade=REMOVE,但我已更改为ALL以尝试解决此问题,但最终会忘记或不更改。谢谢James,这正是发生的事情,但经过许多小时寻找问题,你会变瞎。读了你的建议,我首先认为这不可能,因为我是在分配回复,而我只是在个人内部的电话关系上得到错误。因此,我决定再次查看我的代码,该代码保留该人。在合并该人之前,我正在通过rel循环同步并检查每部电话,然后用数据库中的现有电话进行替换。错误就在这个循环中。
public class Person extends AbstractCRMEntity {
static private final long serialVersionUID = 201111151919L;
@Id @GeneratedValue
private long id;
...
@JoinTable(name="PERSON_TELEPHONES")
@ManyToMany(cascade=CascadeType.ALL)
private Set<Telephone> telephones;
public class Telephone extends AbstractCRMEntity {
static private final long serialVersionUID = 201111151918L;
@EmbeddedId
private TelephoneID phone;
...
@ManyToMany(mappedBy="telephones", fetch=FetchType.LAZY)
private Set<Person> owners;
if (saleEntity.getOwner() != null && saleEntity.getOwner().getId() <= 0) {
OpResult clientResult = personManager.persistPerson(saleEntity.getOwner());
if (clientResult.getOutcome().equals(OpResult.FAILURE)) {
retorno.append(clientResult);
} else {
Person client = (Person) clientResult.getResult();
// if (em.contains(client)) {
// logger.log(Level.INFO, "SalesManagerBean refresh client {0}", client.getName());
// em.refresh(client);
// } else {
// logger.log(Level.INFO, "SalesManagerBean find client {0}", client.getName());
// client = em.find(Person.class, client.getId());
// }
saleEntity.setOwner((Person) clientResult.getResult());
}
}
********************************
if (availableCreditToPay.compareTo(saleEntity.getBalance().getAmount()) > 0) {
em.merge(saleEntity);
// APLLY THE PAYMENTS TO THE SALE UNTIL PAID ...
} else { // not enough unapplied payments to pay
BigDecimal unpaidDifference = saleEntity.getBalance().getAmount().subtract(availableCreditToPay);
if (saleEntity.getOwner().getCreditLimit() != null && saleEntity.getOwner().getCreditLimit().getAmount() != null && saleEntity.getOwner().getCreditLimit().getAmount().floatValue() >= unpaidDifference.floatValue()) { // customer has credit limit
em.merge(saleEntity);
} else { // customer does not have credit limit
if (saleEntity.getCoSigner() == null ? false : (saleEntity.getCoSigner().getCreditLimit().getAmount().floatValue() >= unpaidDifference.floatValue())) {
em.merge(saleEntity);
}
}
}
**********************************