Почему JPA getReference () не работает должным образом? - PullRequest
0 голосов
/ 08 мая 2018

У меня очень странная проблема с методом jpa EntityManager.getReference (). Мой @Entity выглядит следующим образом:

@Entity
@Table(name="people")
public class Person {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @Id
    private long id;

    @Column(name = "full_name")
    private String fullName;

    @Column(name = "location")
    private String location;

    @Column(name = "gender")
    private String gender;

    //getters and setters are omitted

Зависимости Maven:

spring-boot-starter-web 2.0.1.RELEASE
jackson-dataformat-xml  2.9.5
spring-boot-starter-data-jpa 2.0.1.RELEASE
h2 1.4.197

Так при выдаче:

@Autowired
private PersonRepository pr;

@Transactional(propagation=Propagation.REQUIRED)
public void fetch() {
        Person per = pr.getOne(1L);
        per.setGender("male");
}

(getOne () просто делегирует базовый EM getReference ()) Я ожидаю следующего поведения:

update
    people 
set
    gender=?,
where
    id=?

Но на самом деле я получаю следующее:

o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name []: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@577a117e]
o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
org.hibernate.SQL                        : 
        select
            person0_.id as id1_5_0_,
            person0_.full_name as full_nam2_5_0_,
            person0_.gender as gender3_5_0_,
            person0_.location as location4_5_0_ 
        from
            people person0_ 
        where
            person0_.id=?
    o.s.orm.jpa.JpaTransactionManager        : Triggering beforeCommit synchronization
    o.s.orm.jpa.JpaTransactionManager        : Triggering beforeCompletion synchronization
    o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
    o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[domain.Person#1]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
    org.hibernate.SQL                        : 
        update
            people 
        set
            full_name=?,
            gender=?,
            location=? 
        where
            id=?
    o.s.orm.jpa.JpaTransactionManager        : Triggering afterCommit synchronization
    o.s.orm.jpa.JpaTransactionManager        : Triggering afterCompletion synchronization
    o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[domain.Person#1]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] after transaction
    2018-05-08 08:53:30.238 DEBUG 684 --- [nio-8080-exec-5] o.s.orm.jpa.EntityManagerFactoryUtils    : Closing JPA EntityManager

Может быть, я неправильно понял концепцию getReference ()? Или отсутствует какая-то зависимость?

1 Ответ

0 голосов
/ 08 мая 2018

Вы лениво загружаете объект в порядке, но любой вызов метода для этого объекта вызовет фактическую загрузку. Поэтому, когда вы setGender() запустите запрос выбора.

Afaik, если вы хотите обновить, не выбирая сущности (и весь механизм грязной проверки), вы должны выполнить запрос стиля dml (например, update ... set ... where ...), также называемый массовой операцией

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html#batch-direct

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...