JPQL select query causing entity version value to be incremented in an unexpected way

时间:2018-09-18 20:05:28

标签: jpa

I have a simple entity, Presentation (which contains an element collection of an embeddable , but I think that is neither here nor there). EDIT: It seems very much relevant.

I have added a @Version attribute, and found that when I do a simple JPQL select, the version column's value is incremented, but only for one of the two rows that exist in the table.

What I have found is that wrapping the select in a begin and commit (I am working in Java SE) is what causes the version to be or not be incremented. Why is this? Is it because the results of the select enter the EM cache and then upon commit everything in the cache is propagated to the db, regardless of whether any state has changed in the entity?

Whether that is the case or not, can the fact that one row's version is being incremented whereas the other's isn't be explained?

@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        

    }    
}

Main class:

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) { ..//
    }
}

The row with id=1 has its version column consistently updated by the above code, but the row with id=2 does not.

Presentation table:

Presentation

Embeddable collection table:

pres_articles


EDIT Looking at the hibernate debug log info, I can see that update, delete and inserts are created for the row that has an embeddable (id=1); but not for the other row:

  ...
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!

0 个答案:

没有答案