[SPRING] Java / Hibernate - 쓰기 작업은 읽기 전용 모드에서 허용되지 않습니다.
SPRINGJava / Hibernate - 쓰기 작업은 읽기 전용 모드에서 허용되지 않습니다.
나는 최근에 성가신 예외를 많이 겪어 왔으며 Google과이 포럼에 대한 연구를 통해 여전히 내 문제를 해결할 수있는 대답을 찾지 못했습니다.
여기에 - 때로는 최대 절전 모드로 새 객체를 업데이트하거나 만들 때 다음과 같은 오류가 발생합니다.
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1186)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:696)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:694)
실제로 이상한 점은 때로 getHibernateTemplate () 메소드로 객체를 업데이트 할 때입니다. saveOrUpdate (object); 그것은 작동하지만, 때로는 같은 객체를 사용하고 동일한 메소드를 호출하면 작동하지 않지만, 처음 객체를 얻는 방법에 의존하는 것처럼 보입니다.
예 : id, type, length의 3 개 필드가있는 테이블이 있다고 가정 해 보겠습니다. 무슨 일이 일어날 수 있습니다, 만약 내가 ID로 개체를 얻고 길이를 업데이 트하면, 그것은 작동합니다. 유형별로 구하고 길이를 업데이트하면 작동하지 않습니다. 그래서 지금까지 문제를 피하기 위해 내가 해왔 던 것은 나중에 문제를 일으키지 않는 메소드를 가져 오는 것입니다. 그러나 이것은 작동하는 방법을 찾기 위해 점점 더 짜증이 날 것입니다.
또한, 지금은이 예외가 개체를 만들려고 할 때 (그러나 모두 하나의 특정 테이블에만있는 경우), 해결 방법을 찾을 수 없습니다. 그리고 트랜잭션에서 @Transactional (readOnly = false)을 추가하려고 시도했지만 아무 것도 변경하지 않았고 모드를 표시하는 것은 어쨌든 읽기 전용 상태가 아니라고 말하고있었습니다.
어떤 제안?
7 월 26 일 수정 : 최대 절전 모드와 관련된 몇 가지 구성이 있습니다.
<property name="hibernateProperties">
<props>
<prop key="jdbc.fetch_size">20</prop>
<prop key="jdbc.batch_size">25</prop>
<prop key="cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="connection.autoReconnect">true</prop>
<prop key="connection.autoReconnectForPools">true</prop>
<prop key="connection.is-connection-validation-required">true</prop>
</props>
</property>
도움이 될 수도 있다면
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="execute*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
8 월 31 일 수정 : 객체를 저장하기 위해 HibernateDaoSupport를 확장하는 클래스의 관련 코드는 다음과 같습니다.
public void createObject(Object persisObj) {
getHibernateTemplate().save(persisObj);
}
해결법
-
==============================
1.뷰 필터에서 단일 세션 속성을 변경했습니다. 문제 해결됨:
뷰 필터에서 단일 세션 속성을 변경했습니다. 문제 해결됨:
<filter> <filter-name>hibernateFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>false</param-value> </init-param> </filter>
-
==============================
2.이 오류 메시지는 일반적으로 Spring OpenSessionInViewFilter를 사용하고 Spring 관리 트랜잭션 외부에서 지속성 작업을 수행하려고 할 때 나타납니다. 필터는 세션을 FlushMode.NEVER / MANUAL로 설정합니다 (사용중인 Spring 및 Hibernate의 버전에 따라 다름 - 대략 동일합니다). Spring 트랜잭션 메커니즘이 트랜잭션을 시작할 때, 플러시 모드를 "COMMIT"으로 변경한다. 트랜잭션이 완료되면 필요에 따라 NEVER / MANUAL로 다시 설정합니다. 이것이 일어나지 않는다고 확신하는 경우, 다음으로 가장 큰 원인은 세션을 스레드로부터 안전하게 사용할 수 없다는 것입니다. Hibernate Session은 하나의 쓰레드에서만 사용되어야한다. 그것이 쓰레드 사이를 넘으면 모든 종류의 혼돈이 일어날 수 있습니다. Hibernate에서로드 된 엔티티는로드 된 Session에 대한 참조를 보유 할 수 있으며 스레드를 통해 엔티티를 전달하면 다른 스레드에서도 Session에 액세스 할 수 있습니다.
이 오류 메시지는 일반적으로 Spring OpenSessionInViewFilter를 사용하고 Spring 관리 트랜잭션 외부에서 지속성 작업을 수행하려고 할 때 나타납니다. 필터는 세션을 FlushMode.NEVER / MANUAL로 설정합니다 (사용중인 Spring 및 Hibernate의 버전에 따라 다름 - 대략 동일합니다). Spring 트랜잭션 메커니즘이 트랜잭션을 시작할 때, 플러시 모드를 "COMMIT"으로 변경한다. 트랜잭션이 완료되면 필요에 따라 NEVER / MANUAL로 다시 설정합니다. 이것이 일어나지 않는다고 확신하는 경우, 다음으로 가장 큰 원인은 세션을 스레드로부터 안전하게 사용할 수 없다는 것입니다. Hibernate Session은 하나의 쓰레드에서만 사용되어야한다. 그것이 쓰레드 사이를 넘으면 모든 종류의 혼돈이 일어날 수 있습니다. Hibernate에서로드 된 엔티티는로드 된 Session에 대한 참조를 보유 할 수 있으며 스레드를 통해 엔티티를 전달하면 다른 스레드에서도 Session에 액세스 할 수 있습니다.
-
==============================
3.나는 이것에 너무 비틀 거리다. Spring의 OpenSessionInViewFilter에서 플러시 모드를 수동으로 변경해야하고 갑자기이 예외가 발생하기 시작했습니다. @Transactional로 주석 처리되지 않은 메소드에서 문제가 발생했다는 것을 알게되었으므로 Spring은 이러한 메소드 외부의 모든 데이터 액세스 코드를 암시 적으로 읽기 전용으로 취급한다고 생각합니다. 이 방법에 주석을 달면 문제가 해결됩니다.
나는 이것에 너무 비틀 거리다. Spring의 OpenSessionInViewFilter에서 플러시 모드를 수동으로 변경해야하고 갑자기이 예외가 발생하기 시작했습니다. @Transactional로 주석 처리되지 않은 메소드에서 문제가 발생했다는 것을 알게되었으므로 Spring은 이러한 메소드 외부의 모든 데이터 액세스 코드를 암시 적으로 읽기 전용으로 취급한다고 생각합니다. 이 방법에 주석을 달면 문제가 해결됩니다.
또 다른 방법은 HibernateTemplate 객체에서 setCheckWriteOperations 메소드를 호출하는 것이다.
-
==============================
4.더하다
더하다
@Transactional
당신의 기능 위에
-
==============================
5.응용 프로그램 컨텍스트에서 HibernateTemplate에 대해 아래 Bean을 사용하십시오.
응용 프로그램 컨텍스트에서 HibernateTemplate에 대해 아래 Bean을 사용하십시오.
<bean id="template" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="sessionFactory" ref="mysessionFactory"></property> <property name="checkWriteOperations" value="false"></property> </bean>
-
==============================
6.이것을 사용해보십시오.
이것을 사용해보십시오.
hibernateTemplate = new HibernateTemplate(sessionFactory); hibernateTemplate.setCheckWriteOperations(false);
트랜잭션을 사용하고 있는지 여부를 템플릿에서 확인하지 않으므로 오류가 사라집니다.
-
==============================
7.@Transactional 어노테이션을 DAO 서비스 클래스 / 메소드에 추가하는 것을 잊었어야합니다. 그러면 데이터베이스 관리 작업이 스프링 관리 트랜잭션에 의해 처리되도록 지정됩니다.
@Transactional 어노테이션을 DAO 서비스 클래스 / 메소드에 추가하는 것을 잊었어야합니다. 그러면 데이터베이스 관리 작업이 스프링 관리 트랜잭션에 의해 처리되도록 지정됩니다.
-
==============================
8.아래 코드는 저에게 도움이됩니다.
아래 코드는 저에게 도움이됩니다.
hibernateTemplate = new HibernateTemplate(sessionFactory); hibernateTemplate.setCheckWriteOperations(false);
-
==============================
9.1) @Transactional을 데이터베이스 조작 메소드 위에 추가하고 2) 주석 관리 전환 관리자가 있어야합니다.
1) @Transactional을 데이터베이스 조작 메소드 위에 추가하고 2) 주석 관리 전환 관리자가 있어야합니다.
더하다
applicationContext.xml 파일의 HibernateTransactionManager 설정 위
-
==============================
10.나는 같은 문제를 겪었고 어느 날 수사가 끝나자 나는 다음 선언을 관찰했다.
나는 같은 문제를 겪었고 어느 날 수사가 끝나자 나는 다음 선언을 관찰했다.
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
나는 지웠다
mode="aspectj"
그 문제는 사라졌다.
from https://stackoverflow.com/questions/6810158/java-hibernate-write-operations-are-not-allowed-in-read-only-mode by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring 배치에서 여러 데이터 소스 사용 (0) | 2018.12.10 |
---|---|
[SPRING] 다중 데이터 소스와 다중 세션 팩토리를 구성하는 최대 절전 모드 (0) | 2018.12.10 |
[SPRING] 봄 - 코어 3.2.9 + 자바 8 (0) | 2018.12.10 |
[SPRING] 바람둥이가없는 스프링 부트 전쟁 (0) | 2018.12.10 |
[SPRING] Spring 트랜잭션과 hibernate.current_session_context_class (0) | 2018.12.10 |