복붙노트

[SPRING] StaleObjectstateException 행이에 의해 업데이트되거나 삭제되었습니다.

SPRING

StaleObjectstateException 행이에 의해 업데이트되거나 삭제되었습니다.

최대 절전 모드를 사용하는 스프링 프레임 워크를 기반으로하는 웹 응용 프로그램 컨트롤러에서이 예외가 발생합니다. 나는 이것을 대처하기위한 많은 방법을 시도했지만 그것을 해결할 수 없었다.

컨트롤러의 메소드 인 handleRequestInternal에는 submit 액션이 아니라면 주로 'read'에 대한 데이터베이스 호출이있다. 나는 Spring의 Session을 사용했지만 getHibernateTemplate ()로 옮겨 갔고 문제는 여전히 남아있다.

기본적으로이 두 번째 데이터베이스 호출은이 예외를 throw합니다. 그건:

1) getEquipmentsByNumber (number) {먼저 장비가 'number'를 기반으로 DB에서 가져 오며, 여기에는 속성 목록이 있으며 각 속성에는 값 목록이 있습니다. 나는 그 값들 (primitive objects Strings)을 통해 반복하여 변수를 읽는다)

2) getMaterialById (id) {id에 기초한 자료 가져 오기}

두 번째 호출은 아마도 "플러시"세션을 만들고 있지만 실제로는 '읽기'객체 일 뿐이며 두 번째 호출은 변경되지 않은 경우 Equipment 속성에 대한 부실 객체 상태 예외를 throw하는 이유는 무엇인지 이해합니다. ?

호출 후 캐시를 지울 수 없기 때문에 뷰에 전달하는 객체에 LazyExceptions이 발생합니다.

나는 이것을 읽었다. https://forums.hibernate.org/viewtopic.php?f=1&t=996355&start=0 제공된 제안에 따라 문제를 해결할 수는 없습니다.

이 문제를 어떻게 해결할 수 있습니까? 모든 아이디어와 생각은 인정 받고 있습니다.

최신 정보: 방금 테스트 한 것은 getEquipmentsByNumber ()에서 속성 목록에서 변수를 읽은 후이를 수행합니다. getHibernateTemplate (). flush (); 이제는 자료를 가져 오기위한 호출 (getMaterialById (id))이 아니라이 행에서 예외가 발생합니다.

최신 정보: 명시 적으로 flush를 호출하기 전에 세션 캐시에서 객체를 제거하여 부실 객체가 캐시에 남아 있지 않도록합니다.

getHibernateTemplate().evict(equipment);
getHibernateTemplate().flush();

이제는 문제가 DB에서 다음 페치로 이동했습니다. 나는 내가 그 내용을 읽는 것을 끝내자 마자 나는 동기화 된 것으로 레이블을 붙이고 객체를 축출해야한다고 생각한다. 그것은 아주 좋게 들리지 않는다.

최신 정보: handleRequestInternal 메서드를 "synchronized"로 만들었습니다. 오류가 사라졌습니다. 물론, 최선의 해결책은 아니지만 무엇을해야할까요! handleRequestInternal에서 현재 세션을 닫고 새 세션을 열어 보려고했습니다. 하지만 앱의 다른 부분이 제대로 작동하지 않게됩니다. 작동하지 않는 ThreadLocal을 사용하려고했습니다.

해결법

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

    1.Hibernate가 데이터베이스에서 객체를 업데이트하거나 삭제한다고 생각하게하는 어떤 방식으로 Hibernate를 잘못 사용하고있다.

    Hibernate가 데이터베이스에서 객체를 업데이트하거나 삭제한다고 생각하게하는 어떤 방식으로 Hibernate를 잘못 사용하고있다.

    그래서 flush ()를 호출하면 예외가 발생합니다.

    한 가지 가능성 : 서블릿 또는 컨트롤러의 멤버 필드를 통해 세션 또는 엔터티를 잘못 공유하고 있습니다. 이것은 '동기화 된'오류 증상을 변경하는 주된 이유입니다. 짧은 해결책 : 이것을 절대하지 마십시오. 세션 및 엔티티는 이러한 방식으로 작동하지 않아야하며 각 요청은 독립적으로 처리되어야합니다.

    또 다른 가능성 : unsaved-value는 "int"PK 필드의 경우 기본값 0입니다. 실제로 유효한 PK 값으로 0을 사용하려는 경우이를 "정수"로 입력 할 수 있습니다.

    셋째 제안 : Hibernate Session을 명시 적으로 사용하고 작동하는 간단한 코드를 작성한 다음 Hibernate / Spring 라이브러리 용 Java 소스를로드하여이 라이브러리가 실제로 무엇을하는지 읽고 이해할 수 있도록하십시오.

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

    2.나는 또한이 예외로 인해 어려움을 겪어 왔지만, 객체에 자물쇠를 걸었을 때 (그리고 객체를 만지는 유일한 과정 인 것을 알았던 테스트 환경에서) 반복 되어도 계속해서 괄호 안에 스택에서 적절한 고려 사항을 추적합니다.

    나는 또한이 예외로 인해 어려움을 겪어 왔지만, 객체에 자물쇠를 걸었을 때 (그리고 객체를 만지는 유일한 과정 인 것을 알았던 테스트 환경에서) 반복 되어도 계속해서 괄호 안에 스택에서 적절한 고려 사항을 추적합니다.

    우리의 경우 매핑이 잘못 되었음이 드러났습니다. 우리는 데이터베이스에서 중간 텍스트 타입 인 하나의 필드에 대한 매핑에 type = "text"를 가지고 있었고, 적어도 특정 상황에서는 Hibernate가 정말 그것을 싫어하는 것 같습니다. 이 필드의 매핑에서 형식 지정을 모두 제거했으며 문제가 해결되었습니다.

    지금 이상한 점은 프로덕션 환경에서 문제가되는 매핑이 제대로 구현되지 않았기 때문에이 예외가 발생하지 않는다는 것입니다. 왜이게 될지 아무도 몰라요? 우리는 같은 버전의 MySQL을 사용하고 있습니다 - "5.0.22-log"( "-log"가 무엇을 의미하는지 모르겠습니다) - dev 및 production envs.

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

    3.여기에는 3 가지 가능성이 있습니다 (정확하게 모르겠지만 어떤 종류의 최대 절전 모드 세션 처리를 사용하는지). 하나씩 추가하고 테스트합니다.

    여기에는 3 가지 가능성이 있습니다 (정확하게 모르겠지만 어떤 종류의 최대 절전 모드 세션 처리를 사용하는지). 하나씩 추가하고 테스트합니다.

    부모 객체와 자식 객체 사이의 inverse = true를 사용하여 양방향 매핑을 사용하면 부모 또는 자식의 변경 내용이 관계의 다른 끝으로 제대로 전파됩니다.

    TimeStamp 또는 Version 열을 사용하여 낙관적 인 잠금에 대한 지원 추가

    조인 쿼리를 사용하여 두 번째 호출을 모두 피하기 위해 전체 개체 그래프 [상위 + 하위]를 함께 가져옵니다.

    마지막으로, 아무것도 작동하지 않는 경우에만 : 이미 ID를 가지고 부모를로드하고 수정 된 데이터를 채운 다음 업데이트하십시오.

    인생은 좋을 것이다! :)

  4. ==============================

    4.이 문제는 당신이 DAO / Hibernate 호출에서 조금 이상한 일이있어야만했지만, 경험이 풍부하고 실망 스러웠습니다. 왜냐하면 ID로 조회를 수행하면 부실 상태를 얻을 이유가 없기 때문입니다 이것은 객체에 대한 단순한 조회이기 때문입니다.

    이 문제는 당신이 DAO / Hibernate 호출에서 조금 이상한 일이있어야만했지만, 경험이 풍부하고 실망 스러웠습니다. 왜냐하면 ID로 조회를 수행하면 부실 상태를 얻을 이유가 없기 때문입니다 이것은 객체에 대한 단순한 조회이기 때문입니다.

    먼저, 모든 메소드가 @Transaction (required = true)로 주석되어 있는지 확인하십시오. // 정확한 구문을 찾아야합니다.

    그러나이 예외는 일반적으로 검색된 세션에서 분리 된 객체를 변경하려고 할 때 발생합니다. 이 문제에 대한 해결책은 간단하지 않고 더 많은 코드를 게시해야하므로 상황을 정확히 볼 수 있습니다. 내 일반적인 제안은 단일 트랜잭션 내에서 이러한 종류의 작업을 수행하는 @Service를 작성하는 것입니다.

  5. from https://stackoverflow.com/questions/3158491/staleobjectstateexception-row-was-updated-or-deleted-by by cc-by-sa and MIT license