Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee OptMisticLocking内部字段异常_Jakarta Ee_Jpa_Jpa 2.0 - Fatal编程技术网

Jakarta ee OptMisticLocking内部字段异常

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()返回时持

我有一个Person类,它是各种其他交易的一部分,例如销售或付款。我有这个人类链接到支付和销售以及没有级联。所以,当我想坚持销售,也有付款。我这样做

OBS:我有SalesBean、PaymentBean、PersonBean

1-Sales Bean首先尝试持续付款。
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);
                }
        }
}

**********************************