복붙노트

[SPRING] Jpa 및 Hibernate는 DB에서 비동기 적으로 변경되는 데이터를로드합니까?

SPRING

Jpa 및 Hibernate는 DB에서 비동기 적으로 변경되는 데이터를로드합니까?

나는 내 db 쿼리에 오라클보기가 있습니다.

create or replace view my_view as
Select cc.CCID ccid
       sm.SMCODE smcode,
       NVL(sm.smname, cc.ccname) sname
  From CC cc
 Inner Join SM sm
    On cc.id = sm.id;

내보기를 내 엔터티에 매핑하는 데 jpa 2.1 및 최대 절전 모드 4.3.7을 사용합니다. 내 엔티티 클래스는 다음과 같습니다.

public class CCRequest implements Serializable {

    private static final long serialVersionUID = 1L;

    private String ccId;

    private String smCode;

    private String sName;
}

그리고 내 매핑 XML은 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 version="2.1">
    <entity class="CCRequest" name="CCRequest001">
        <table name="my_view"/>
        <attributes>
            <id name="ccId">
                <column name="ccid"/>
            </id>
            <basic name="smCode">
                <column name="smcode"/>
            </basic>
            <basic name="sName">
                <column name="sname"/>
            </basic>
        </attributes>
    </entity>
</entity-mappings> 

그래서 jpa를 사용하여 엔티티를 올바르게 쿼리하면 모든 레코드가 반환됩니다. 다음은 문제입니다. DB에서 비동기 적으로 데이터를 변경하면 놀랍게도 내 jpa 쿼리는 이전 레코드를 반환합니다. 내가 잘못 했니?

해결법

  1. ==============================

    1.Hibernate는 이전 결과를 캐쉬하므로 연관된 캐쉬를 정리하기 위해 entityManager.clear ()를 사용해야한다. 조회를 다시 실행해야합니다. 자세한 내용은 관련 스레드 :

    Hibernate는 이전 결과를 캐쉬하므로 연관된 캐쉬를 정리하기 위해 entityManager.clear ()를 사용해야한다. 조회를 다시 실행해야합니다. 자세한 내용은 관련 스레드 :

    Hibernate 캐싱에 대한 추가 정보 :

    또 다른 옵션은 entityManager.refresh (obj)를 사용하여 데이터베이스 데이터를 세션 데이터와 동기화하는 것입니다.

  2. ==============================

    2.JPA에는 데이터베이스를 업데이트하는 다른 프로세스에 대한 사전 지식이 없으므로 어떻게 될까요? 당신은 그 사실을 알고 그것을 사용해야 만하는 유일한 사람입니다.

    JPA에는 데이터베이스를 업데이트하는 다른 프로세스에 대한 사전 지식이 없으므로 어떻게 될까요? 당신은 그 사실을 알고 그것을 사용해야 만하는 유일한 사람입니다.

    em.refresh(obj)
    

    데이터가 변경되었을 가능성이있는 경우 객체를 업데이트합니다.

  3. ==============================

    3.내가 직면 한 문제는 4 이전의 spring에서 jpa 엔티티와 작업하기 위해 JpaTemplate을 사용했기 때문에 EntityManagerFactory의 인스턴스에서 JpaTemplate의 인스턴스에 EntityManager를 문제없이 전달했습니다. JpaTemplate 자체는 EntityManager를 플러시하고 캐시를 비우는 데 필요한 모든 작업을 수행합니다. Spring 4로 마이그레이션 할 때 JpaTemplate이 삭제되어 EntityManager와 직접 작업해야합니다. EntityManagerFactory의 인스턴스에서 EntityManager 인스턴스를 프로그래밍 방식으로 얻습니다. EntityManagerFactory 인스턴스에서 EntityManager 인스턴스를 만드는 EntityManagerProvider 클래스가 있습니다.

    내가 직면 한 문제는 4 이전의 spring에서 jpa 엔티티와 작업하기 위해 JpaTemplate을 사용했기 때문에 EntityManagerFactory의 인스턴스에서 JpaTemplate의 인스턴스에 EntityManager를 문제없이 전달했습니다. JpaTemplate 자체는 EntityManager를 플러시하고 캐시를 비우는 데 필요한 모든 작업을 수행합니다. Spring 4로 마이그레이션 할 때 JpaTemplate이 삭제되어 EntityManager와 직접 작업해야합니다. EntityManagerFactory의 인스턴스에서 EntityManager 인스턴스를 프로그래밍 방식으로 얻습니다. EntityManagerFactory 인스턴스에서 EntityManager 인스턴스를 만드는 EntityManagerProvider 클래스가 있습니다.

    public class EntityManagerProvider {
    
        public static EntityManager createEntityManager(EntityManagerFactory entityManagerFactory) {
            return entityManagerFactory.createEntityManager();
        }
    }
    

    나는 entityManager 인스턴스를 다음과 같이 얻는다.

    <bean id="entityManager" class="com.tosan.novin.sipa.bo.da.jpa.EntityManagerFactoryProvider" factory-method="createEntityManager">
            <constructor-arg index="0" ref="entityManagerFactory"/>
    </bean>
    

    그러나 EntityManager가 트랜잭션을 관리하고 플러시하는 유일한 방법은 @PersistenceContext를 사용하여 Bean에 EntityManager를 주입하는 것입니다.

    @PersistenceContext
    protected EntityManager em;
    

    나는이 방법으로 조금 혼란 스럽다. 그러나이 방법으로 내 문제를 해결했다.

  4. from https://stackoverflow.com/questions/39022586/do-jpa-hibernate-load-data-which-changes-asynchronously-in-db by cc-by-sa and MIT license