为什么JPA乐观锁定会在一次交易中两次递增我的实体版本(@Version)?

时间:2015-04-25 17:28:08

标签: jpa eclipselink derby glassfish-4

我正在使用GlassFish 4.1,EclipseLink和Derby开发Java EE应用程序,并且今天注意到当我创建一个新的Person实体时,新创建的实体的版本是2而不是1.以下是我的Person Entity。

@Entity
public class Person {

    @Id
    private Long id;
    @Version
    private Integer version;

    private String name;

    @OneToOne
    private Portrait portrait;

    @OneToMany(mappedBy = "person")
    private List<Portrait> portraits;

    ...

}

以下是我的肖像实体。

@Entity
public class Portrait {

    @Id
    private Long id;
    @Version
    private Integer version;

    private String name;

    @ManyToOne
    private Person person;

    ...

}

以下是我的无状态EJB createPerson方法的一部分,该方法导致新创建的Person实体的版本为2.

Person person = new Person();
person.setName("Fred Smith");

em.persist(person);

Portrait portrait = new Portrait();
portrait.setName("Fred Smith Portrait");
portrait.setPerson(person);

portrait = portraitManager.createPortrait(portrait);  //portraitManager is another stateless EJB.

person.setPortrait(portrait);    // Commenting out this line results in newly created Person entity with a version of 1.
person.getPortraits().add(portrait);

如果我注释掉上面的person.setPortrait(portrait)行,则使用版本1创建Person实体。

我在其他帖子中读到,如果字段更改或拥有的关系发生更改,JPA将增加实体的版本。方法从createPortrait方法返回后,我正在更改拥有的关系,但我仍然在同一个事务中,所以不明白为什么JPA需要增加版本。

为什么JPA会在同一个事务中两次增加Person实体的版本?

根据评论中的要求,我打开了EclipseLink日志记录,并在正常流程中观察到以下内容:

  1. 应用程序启动createPerson方法。
  2. EclipseLink将行插入到人员表中。
  3. 应用程序启动createPortrait方法。
  4. EclipseLink将行插入纵向表。
  5. 应用程序完成createPortrait方法。
  6. 应用程序将新创建的肖像与人员关联。
  7. EclipseLink更新row in person表,将版本设置为2,将portrait_id设置为新创建的肖像。
  8. 应用程序完成createPerson方法。
  9. 如果我评论出“person.setPortrait(Portrait);”命令,日志显示以下内容:

    1. 应用程序启动createPerson方法。
    2. EclipseLink将行插入到人员表中。
    3. 应用程序启动createPortrait方法。
    4. EclipseLink将行插入纵向表。
    5. 应用程序完成createPortrait方法。
    6. 应用程序完成createPerson方法。
    7. 为了更具体地说明我的问题,为什么EclipseLink会更新正常流程的第7步中的版本? EclipseLink在步骤2中创建了版本1的行,并且没有其他事务更新该行,因为该行只存在于此事务中,直到提交为止。

      我怀疑答案是这只是EclipseLink选择在这种情况下工作的方式。

0 个答案:

没有答案