首页 > 解决方案 > JPQL 选择查询导致实体版本值以意外方式增加

问题描述

我有一个简单的实体,Presentation(它包含一个可嵌入的元素集合,但我认为这既不存在也不存在)。编辑:这似乎非常相关。

我添加了一个@Version 属性,发现当我进行简单的JPQL 选择时,版本列的值会增加,但仅针对表中存在的两行之一。

我发现将选择包装在开始和提交中(我在 Java SE 中工作)是导致版本增加或不增加的原因。为什么是这样?是因为选择的结果进入了 EM 缓存,然后在提交时缓存中的所有内容都会传播到数据库,而不管实体中是否有任何状态发生变化?

不管是不是这样,一行的版本正在递增而另一行的版本没有被解释这一事实是否可以解释?

@Entity
@Table(name="PRESENTATION")
public class Presentation {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id;
    private String name;

    @Version
    private int version;

    @ElementCollection
    @CollectionTable(name="PRES_ARTICLES", joinColumns=@JoinColumn(name="pres_id"))
    Set<Article> referencedArticles;
//..getters setters etc        

    }    
}

主类:

static void selectPresData() {
    try {
        em.getTransaction().begin();
        System.out.println("before query..");
        em.createQuery("SELECT p FROM Presentation p", Presentation.class)
                .getResultList()
                .forEach(System.out::println); 
        System.out.println("before commit..");
        em.getTransaction().commit();

    } catch (Exception e) { ..//
    }
}

id=1 的行的版本列由上面的代码一致更新,但 id=2 的行没有。

演示表:

介绍

可嵌入的集合表:

pres_articles


编辑 查看休眠调试日志信息,我可以看到为具有可嵌入 (id=1) 的行创建了更新、删除和插入;但不适用于另一行:

  ...
21:20:08,242 INFO  [Main.class] - running!
before query..
21:20:08,261 DEBUG [org.hibernate.SQL] - select presentati0_.id as id1_4_, presentati0_.name as name2_4_, presentati0_.version as version3_4_ from PRESENTATION presentati0_
21:20:08,327 DEBUG [org.hibernate.SQL] - select referenced0_.pres_id as pres_id1_3_0_, referenced0_.name as name2_3_0_ from PRES_ARTICLES referenced0_ where referenced0_.pres_id=?
Presentation [id=1, name=JPA 101, articles=[Article [name=How to use cascadeType], Article [name=How to use shared cache]]]
21:20:08,338 DEBUG [org.hibernate.SQL] - select referenced0_.pres_id as pres_id1_3_0_, referenced0_.name as name2_3_0_ from PRES_ARTICLES referenced0_ where referenced0_.pres_id=?
Presentation [id=2, name=Stats 101 and Toastmaking 101, articles=[]]
before commit..
21:20:08,365 DEBUG [org.hibernate.SQL] - update PRESENTATION set name=?, version=? where id=? and version=?
21:20:08,386 DEBUG [org.hibernate.SQL] - delete from PRES_ARTICLES where pres_id=?
21:20:08,387 DEBUG [org.hibernate.SQL] - insert into PRES_ARTICLES (pres_id, name) values (?, ?)
21:20:08,399 DEBUG [org.hibernate.SQL] - insert into PRES_ARTICLES (pres_id, name) values (?, ?)
21:20:08,480 INFO  [org.hibernate.orm.connections.pooling] - HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/JPA2?useSSL=false]
21:20:08,482 INFO  [Main.class] - done!

标签: jpa

解决方案


推荐阅读