2017-10-25 1 views
0

데이터베이스 또는 JPA 캐시에서 모든 엔티티를 반환하는 all()이라는 메서드로 추상 DAO 클래스가있는 tomcat에서 실행되는 webapp에 문제가 있습니다. 첫 번째 호출에서 엔티티를 올바르게 반환하는 것으로 보이지만 이후 호출은 엔티티 관리자 find 메소드를 사용하여 목록에서 특정 엔티티를 찾고 관련 필드를 업데이트하고 커밋하는 별도 UI 호출에서 발생하는 업데이트를 반영하지 않습니다. 같은 all() 메서드를 통해 해당 목록을 볼 때 나중에 원래 값이 표시됩니다. 로그에서 다른 업데이트를 작성하면 올바른 값 (원래 값이 아님)에서 업데이트 된 값으로 변경되는 값을 볼 수 있으며 로그에는 매번 올바르게 발생하는 업데이트가 표시됩니다.JPA 쿼리가 업데이트 된 결과를 목록에 반환하지 않습니다.

저는 주입 용 guice를 사용하고 있습니다. 나는 로깅에 대해 놀았고 요청을 통해 사용되었지만 요청마다 다른 엔티티 관리자에서 동일한 해시 코드를 볼 수 있습니다. 나는 나의 모든() 업데이트 반환하지 않습니다 결과, 나는했습니다 왜 볼 수없는

<property name="eclipselink.cache.shared.default" value="false" /> 
    <shared-cache-mode>NONE</shared-cache-mode> 

... (가) 중 하나 도움을 보이지 않았다 persistance.xml 파일을 다음과 같이 해본 적이 또한 내 쿼리가 재사용되고 나타납니다 그래서 나는 다음을 호출하여 교체 한 다음 목록에서 업데이트하고있어 특정 개체 ...

entity = em.find(Class.class, id) 

는 특정 개체에 대한 문제를 해결하기 위해 듯를 찾기 위해 코드를 추가하는 시도 늙은.

여기

private final Provider<EntityManager> emP; 

protected EntityManager em(boolean useTransaction) throws DaoException { 
    return useTransaction ? begin() : emP.get(); 
} 

public List<T> all() throws DaoException { 
    EntityManager em = em(false); 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<T> cq = cb.createQuery(eClass); 
    Root<T> from = cq.from(eClass); 
    return em.createQuery(cq.select(from)).getResultList(); 
} 

public T save(T t) throws DaoException { 
    return save(t, em(true)); 
} 

protected T save(T t, EntityManager em) throws DaoException { 
    if (Objects.isNull(t)) { 
     throw new DaoException("can't save null object: " + getDaoClass(), new NullPointerException()); 
    } 

    T saved; 
    if (t.getId() > 0) { 
     saved = em.merge(t); 
    } else { 
     em.persist(t); 
     saved = t; 
    } 

    autoCommit(); 
    return saved; 
} 

protected void autoCommit() throws DaoException { 
    if (autoCommit) { 
     commit(); 
    } 
} 

public void commit() throws DaoException { 
    EntityManager em = emP.get(); 
    if (!em.getTransaction().isActive()) { 
     throw new DaoException("transaction isn't active, unable to commit"); 
    } 

    try { 
     em.getTransaction().commit(); 
    } catch (IllegalStateException e) { 
     throw new DaoException("transaction not active", e); 
    } catch (RollbackException e) { 
     throw new DaoException("commit rolled back", e); 
    } 
} 

내 DAO 클래스에서 코드 조각의 사람이 이런 일이있을 아니면 확인하려고 수있는 다른 무엇에 대한 어떤 제안이 이유에 어떤 통찰력이 있다면 그래서 내가 궁금하네요?

+1

emP는 항상 첫 번째 수준 캐시의 결과를 반환하는 동일한 em을 반환합니다. 트랜잭션없이 JPA를 사용할 수 있다고 생각하지 마십시오. EM을 오랫동안 열어 두십시오. 당신은 할 수 없습니다. 항상 새로운 EM을 얻고, 트랜잭션을 시작하고, 당신이해야 할 일 (읽기 및/또는 쓰기)을 수행하고 커밋하십시오. –

+0

지금 시도해 보겠습니다. – Arran

+0

useTransaction boolean을 무시하고 EntityManager em (boolean useTransaction) 메소드를 변경하고 트랜잭션을 시작한 다음 my all() 메소드의 끝 부분에 커밋을 추가했지만 여전히 동일한 결과를 산출했습니다. 또한 나는 그것을 열어 두지 않을거야 guice를 사용하여 각 요청마다 새로운 엔티티 관리자를 주입하는 guice를 사용하고있다. UnitOfWork – Arran

답변

0

그래서 내가 가진 문제의 원인을 발견했습니다. 목록을 참조 할 때 내 엔티티에서 ElementCollection 주석을 사용하고있었습니다. 주석을 제거하고 JoinTable 및 OneToMany 주석으로 대체하고 모든 것이 올바르게 작동합니다.

문제는 엔티티가 데이터베이스에 잘 저장되고 예상대로 엔티티를 업데이트했지만 JPA가 참조 된 엔티티 목록을 포함 시켰습니다.

그래서 업데이트 된 실제 엔티티가 아닌 매번 반환 된 임베디드 목록을보고있었습니다. 내 개체가 이제 포함 된 개체 대신 적절한 조인 테이블을 사용하고 모든 것이 예상대로 작동합니다.

관련 문제