JPA Hibernate - 不能在同一个实体事务中持久化和执行更新查询

时间:2018-04-20 06:12:01

标签: java hibernate jpa

我一直试图坚持一个实体实例,然后就在那之后 通过JPQL查询更新同一个实体实例。 两个操作都参与实体事务,但在提交后, 更新查询似乎尚未执行或在提交之前已执行。

如何做到对不对?

代码:

    EntityManager em = getEntityManager();
    EntityTransaction transaction = em.getTransaction();
    transaction.begin();

    Person person = new Person();
    person.setAge(25);
    person.setName("John Ive");
    em.persist(person);

    Query q = em.createQuery("Update Person p set p.age=27 where p.personId=:id");
    q.setParameter("id",person.getPersonId());
    q.executeUpdate();
    transaction.commit();

Person.java

@Entity
public class Person {
    @Id
    @GeneratedValue
    private int personId;
    private String name;
    private int age;

    //Getters and setter here
}

的persistence.xml

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
         version="2.1">

<persistence-unit name="example-db" transaction-type="RESOURCE_LOCAL">

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>example.entities.Person</class>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
        <property name="hibernate.archive.autodetection" value="class, hbm" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
        <property name="hibernate.connection.autocommit" value="false" />
        <property name="hibernate.connection.release_mode" value="after_transaction" />
        <property name="org.hibernate.flushMode" value="commit" />
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.user" value="sa"/>
        <property name="javax.persistence.jdbc.password" value=""/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
    </properties>

</persistence-unit>

Hibernate日志:

    08:27:42.847 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - begin
    08:27:42.854 [main] DEBUG org.hibernate.SQL - call next value for hibernate_sequence
    Hibernate: call next value for hibernate_sequence
    08:27:42.860 [main] DEBUG org.hibernate.id.enhanced.SequenceStructure - Sequence value obtained: 1
    08:27:42.860 [main] DEBUG org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl - HHH000387: ResultSet's statement was not registered
    08:27:42.863 [main] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 1, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
    08:27:42.881 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
    08:27:42.882 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Dirty checking collections
        08:27:42.885 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
        08:27:42.885 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
        08:27:42.888 [main] DEBUG org.hibernate.internal.util.EntityPrinter - Listing entities:
        08:27:42.888 [main] DEBUG org.hibernate.internal.util.EntityPrinter - example.entities.Person{name=John Ive, personId=1, age=25}
        08:27:42.896 [main] DEBUG org.hibernate.SQL - insert into Person (age, name, personId) values (?, ?, ?)
        Hibernate: insert into Person (age, name, personId) values (?, ?, ?)
        08:27:42.913 [main] DEBUG org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - QueryTranslatorFactory : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory@615f972
        08:27:42.913 [main] INFO org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
        08:27:42.942 [main] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - parse() - HQL: Update example.entities.Person p set p.age=27 where p.personId=:id
        08:27:42.952 [main] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - --- HQL AST ---
         \-[UPDATE] Node: 'Update'
            +-[FROM] Node: 'FROM'
            |  \-[RANGE] Node: 'RANGE'
            |     +-[DOT] Node: '.'
            |     |  +-[DOT] Node: '.'
            |     |  |  +-[IDENT] Node: 'example'
            |     |  |  \-[IDENT] Node: 'entities'
            |     |  \-[IDENT] Node: 'Person'
            |     \-[ALIAS] Node: 'p'
            +-[SET] Node: 'set'
            |  \-[EQ] Node: '='
            |     +-[DOT] Node: '.'
            |     |  +-[IDENT] Node: 'p'
            |     |  \-[IDENT] Node: 'age'
            |     \-[NUM_INT] Node: '27'
            \-[WHERE] Node: 'where'
               \-[EQ] Node: '='
                  +-[DOT] Node: '.'
                  |  +-[IDENT] Node: 'p'
                  |  \-[IDENT] Node: 'personId'
                  \-[COLON] Node: ':'
                     \-[IDENT] Node: 'id'

        08:27:42.952 [main] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
        08:27:42.992 [main] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - update << begin [level=1, statement=update]
        08:27:43.015 [main] DEBUG org.hibernate.hql.internal.ast.tree.FromElement - FromClause{level=1} : example.entities.Person (p) -> person0_
        08:27:43.017 [main] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : p -> personId
        08:27:43.020 [main] DEBUG org.hibernate.hql.internal.ast.tree.DotNode - getDataType() : age -> org.hibernate.type.IntegerType@309e345f
        08:27:43.022 [main] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : p.age -> age
        08:27:43.028 [main] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : p -> personId
        08:27:43.028 [main] DEBUG org.hibernate.hql.internal.ast.tree.DotNode - getDataType() : personId -> org.hibernate.type.IntegerType@309e345f
        08:27:43.028 [main] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : p.personId -> personId
        08:27:43.031 [main] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - update : finishing up [level=1, statement=update]
        08:27:43.032 [main] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - update >> end [level=1, statement=update]
        08:27:43.033 [main] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - --- SQL AST ---
         \-[UPDATE] UpdateStatement: 'Update'  querySpaces (Person)
            +-[FROM] FromClause: 'FROM' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[p], fromElementByTableAlias=[person0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
            |  \-[FROM_FRAGMENT] FromElement: 'Person' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=p,role=null,tableName=Person,tableAlias=person0_,origin=null,columns={,className=example.entities.Person}}
            +-[SET] SqlNode: 'set'
            |  \-[EQ] BinaryLogicOperatorNode: '='
            |     +-[DOT] DotNode: 'age' {propertyName=age,dereferenceType=PRIMITIVE,getPropertyPath=age,path=p.age,tableAlias=person0_,className=example.entities.Person,classAlias=p}
            |     |  +-[ALIAS_REF] IdentNode: 'personId' {alias=p, className=example.entities.Person, tableAlias=person0_}
            |     |  \-[IDENT] IdentNode: 'age' {originalText=age}
            |     \-[NUM_INT] LiteralNode: '27'
            \-[WHERE] SqlNode: 'where'
               \-[EQ] BinaryLogicOperatorNode: '='
                  +-[DOT] DotNode: 'personId' {propertyName=personId,dereferenceType=PRIMITIVE,getPropertyPath=personId,path=p.personId,tableAlias=person0_,className=example.entities.Person,classAlias=p}
                  |  +-[ALIAS_REF] IdentNode: 'personId' {alias=p, className=example.entities.Person, tableAlias=person0_}
                  |  \-[IDENT] IdentNode: 'personId' {originalText=personId}
                  \-[NAMED_PARAM] ParameterNode: '?' {name=id, expectedType=org.hibernate.type.IntegerType@309e345f}

        08:27:43.033 [main] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
        08:27:43.048 [main] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
        08:27:43.066 [main] DEBUG org.hibernate.SQL - update Person set age=27 where personId=?
        Hibernate: update Person set age=27 where personId=?
        08:27:43.068 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - committing
08:27:43.069 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
08:27:43.069 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Dirty checking collections
08:27:43.069 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
08:27:43.070 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections

2 个答案:

答案 0 :(得分:0)

试试这个:

if (name.startsWith("a") || name.startsWith("e")//....rest of check)

答案 1 :(得分:-1)

尝试entitymanager.refresh()。对我有用