@Entity Class의 property에서

다른 @Entity Class를 참조하며

 

@ManyToOne(fetch = FetchType.LAZY) 를 주었다면

 

해당 property로 접근하려고 할 때는...?

뭐 다른 일이 일어날게 없다...  ㅡㅡ;;;

 

뭐 흔하게 계~~~속 잘~~~ 써 왔던 경우인데...

 

어느 날 갑자기, 뜬금없이, 아무리 생각해도 이해를 하지 못할...

아래처럼 LazyInitializationException 이 나왔다면...

 

org.hibernate.LazyInitializationException: could not initialize proxy [common.model.entity.P#2915] - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:155)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:268)
        at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)

        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

        at sun.reflect.GeneratedMethodAccessor180.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

 

 

혹시... 해당 Class에서

@Scheduled 를 사용하고 있지 않은가?

 

 

그렇다면

@Scheduled 를 사용하는 Class와

Entity를 처리하는 Class를 분리해야 한다.

 

org.springframework.boot 2.0.8

spring-context 5.0.12

이 환경에서는 분리하니...

언제 그랬냐는 듯이...

잘 돌아간다...;;;

 

 

이런 경우는...

정말 만나고 싶지 않아...

 

 

'plming > Java-Spring Boot' 카테고리의 다른 글

파일 Upload 크기 제한 설정  (0) 2019.06.16

하나의 DATA값이

여러 Byte로 저장되는 경우

CPU마다 처리순서가 다르다.

 

숫자 769를 4 Byte 공간에 넣는다고 했을 때

큰 숫자가 앞에 있다고 인식하고 처리하는 Big Endian

(이때 저장된 Hex값은 0x00 0x00 0x03 0x01 으로 저장되어있다.)

 

작은 숫자가 앞에 있다고 인식하고 처리하는 Little Endian

(이때 저장된 Hex값은 0x01 0x03 0x00 0x00 으로 저장되어있다.)

 

 

그런데, 뭐?

Local에서 지지고 볶을 때는 관계없다.

 

하지만, 네트웍을 통해 전달하는 경우

주는 쪽에서 생성한 방식과

받는 쪽에서 인식해야 하는 방식이 다르다면?

769원이

16,973,824원으로 인식될 수도 있게된다.

 

 

이때 양쪽의 처리방식을 맞추면

동일한 값으로 인식할 수 있다.

 

내 PC의 처리방식(Byte Order)는 뭘까?

 ByteOrder.nativeOrder();

ByteOrder.BIG_ENDIAN 과 ByteOrder.LITTLE_ENDIAN 중 하나가 나온다.

 

 

됐고, 난 이걸로 할꺼야.

원하는 처리방식으로 Byte 배열을 얻고 싶다면?

769를 Little Endian 값으로 받고 싶다면?

 ByteBuffer byteBuffer = ByteBuffer.allocate( Integer.BYTES );
 byteBuffer.clear();
 byteBuffer = byteBuffer.order( ByteOrder.LITTLE_ENDIAN );
 int value = 769;
 byteBuffer.putInt( value );
 byte[] bytes = byteBuffer.array();

 

clear 와 order 를 실행하지 않으면 꽝!!!

 

내 PC의 처리방식이 뭐든지간에

JAVA는 기본적으로 BIG_ENDIAN으로 생성된다.

이걸 잊어도 꽝!!!

 

잘 챙겨서

날 벼락 맞는 일 생기지 않기를...

 

 

오늘날짜의 00시 구하기

 SELECT SUBTIME( NOW(), TIMEDIFF( NOW(), CAST(DATE(NOW()) AS DATETIME) ) )
 ;

 

오늘날짜의 00시 구하기

(UTC인 시간을 우리나라 시간으로)

 SELECT SUBTIME( NOW()
               , TIMEDIFF( CONVERT_TZ(NOW(), @@system_time_zone, 'Asia/Seoul')
                         , CAST(DATE( CONVERT_TZ(NOW(), @@system_time_zone, 'Asia/Seoul') ) AS DATETIME)
                         )
               )
 ; 

 

 

DB 시간이 어느 TimeZone인가 확인할 때

 SELECT @@system_time_zone

 ;

 

DB 시간이 우리나라 시간이 아니라면

DB의 현재 시간을, 우리나라 시간으로 바꿔서 조회하고 싶다면

 SELECT NOW(), CONVERT_TZ(NOW(), @@system_time_zone, 'Asia/Seoul')

 ;

 

 

시스템 운영시점에서는 설정된 기본값이나

조정된 설정값을 사용하면 되지만

 

DB에 실행시간이 길게 소요되는 SQL들을 날리며 작업해야하는

DB Setting, Migration등의 경우

DB 자체에서 관리하는 timeout 값들을 변경한 후 작업을 수행하고

작업이 완료되면, 원래 설정값들로 원복하는 것이

정신건강에 좋을 듯 하다.

 

그렇지 않으면

아래 Error를 작업이 끝날 때까지 만나게 될테니 말이다.

(작업이 수행되다 중간에 끊어져버린 것이라...

 100을 처리해야 하는 데, 60, 70만 처리되고 끝나버리면

 작업을 보정하기 조차 어렵다;;;  (정신건강에 안좋음)

 60, 70이라도 작업을 초기화해야 할 듯...

 Error Code: 2013. Lost connection to MySQL server during query

 

MySQL에는 timeout 관련 설정이 다수 있지만

 SHOW VARIABLES LIKE '%timeout%';

 

 Variable_name Value
 connect_timeout 10
 delayed_insert_timeout 300
 have_statement_timeout YES
 innodb_flush_log_at_timeout 1
 innodb_lock_wait_timeout 50
 innodb_rollback_on_timeout OFF
 interactive_timeout 28800
 lock_wait_timeout 31536000
 net_read_timeout 30
 net_write_timeout 60
 rpl_stop_slave_timeout 31536000
 slave_net_timeout 60
 wait_timeout 28800 

 

오래 걸리는 SELECT를 처리해야 할 때는

 SET GLOBAL net_read_timeout = 30;

 

오래 걸리는 INSERT, UPDATE를 처리해야 할 때는

 SET GLOBAL net_write_timeout = 60;

 

원하는 초단위로 변경하고

재접속하면 된다.

 

작업이 완료되고 난 후에는...

설정값을 원복하는 것을 잊으면 안되겠다...

놀이터가 아니라면...^^

 

 

기타 설정값 관련 참고글 : https://lilymate.tistory.com/640

 

MySQL - Temp Table is full, 크기 조절

CREATE TEMPORARY TABLE xxx ... 임시로 생성한 테이블에서 아래와 같은 Exception 이 발생한다면? java.sql.SQLException: The table 'xxx' is full MySQL 환경에 설정된 heap size와 temp table size를 조절해야..

lilymate.tistory.com

 

 

- 기본은 1MB

- multipart/form-data 로 받을 수 있는 것은 10MB

 

https://docs.spring.io/spring-boot/docs/2.0.x/api/org/springframework/boot/autoconfigure/web/servlet/MultipartProperties.html

 

MultipartProperties (Spring Boot Docs 2.0.10.BUILD-SNAPSHOT API)

Properties to be used in configuring a MultipartConfigElement. location specifies the directory where uploaded files will be stored. When not specified, a temporary directory will be used. max-file-size specifies the maximum size permitted for uploaded fil

docs.spring.io

 

- src/main/resources/application.properties 에 아래 설정들로 조정할 수 있다.

- 기본

 spring.servlet.multipart.max-file-size=128KB
 spring.servlet.multipart.max-request-size=128KB

- multipart/form-data 로 받는

 spring.http.multipart.max-file-size=128KB
 spring.http.multipart.max-request-size=128KB

https://spring.io/guides/gs/uploading-files/

#Tuning file upload limits

 

하지만, Rest API로 만들고

Swagger로 Test하려할 때 multipart/form-data가 제대로 안되는 것 같을 때

기본 설정을 추가해주면 Swagger에서도 Test가 잘 된다.

 

 

+ Swagger Tip 하나 더

@RequestBody가 아닌

@RequestPart xxxDto 로 정의한 경우

Swagger에서는 1개의 InputBox로만 표시되는데...

 

xxxDto의 모든 항목을 입력해야 할 때는

아래처럼 여러개의 값을 갖는 json 형태로 입력하면 Test할 수 있다.

 { "aaa": "111", "bbb": "222" }

 

 

'plming > Java-Spring Boot' 카테고리의 다른 글

원인모를 LazyInitializationException - no Session  (2) 2020.05.25

ubuntu에서

 

현재 어떻게 실행되어있는지 확인

# lsof -iTCP -sTCP:LISTEN -P | grep apache2 | grep 80

 apache2   14254 www-data    4u  IPv4 8302072      0t0  TCP *:80 (LISTEN)
 apache2   14254 www-data    4u  IPv6 8302072      0t0  TCP *:80 (LISTEN) 

 

혹은 netstat를 사용해도 되지만,

 # netstat -nlt | grep 80

 tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
 tcp6       0      0 :::80                    :::*                      LISTEN

좀 더 명확하게 표시되니...

 

 

Apache2 설정파일 수정

# sudo vi /etc/apache2/ports.conf

 

Listen 80 을  ← (IPv4/IPv6 모두 실행되는 것이지만... IPv6만 실행되서 서비스가 안될 때가 있다)

 

Listen 0.0.0.0:80 으로 수정 후 저장

 

 

Apache2 재실행

# /etc/init.d/apache2 restart

 

다시 확인해보면, IPv4 만 실행되어있다.

 

그런데도, 80 port로의 서비스가 바로 접근이 안된다면...?

VirtualHost 등으로 연결된 상황이라면 더더욱...

 

조금 기다려야 정상(?!)속도로 나오는 듯 하다...;;;

 

 

mysql - DB Link, FEDERATED TABLE 생성 (1/2) - 준비

 


2. DB Link 처리할 TABLE 생성

   그렇다.  MySQL에서는 TABLE을 만들어야 원격 DB의 해당 TABLE을 접근할 수 있다.

              접근할 TABLE을 1:1로 모두 생성시켜야 한다.

 

2.1. 접속정보를 모두 입력해서 TABLE 생성

 

 CREATE TABLE 테이블명 { ... }

 ENGINE=FEDERATED ...

 CONNECTION='mysql://user_name[:password]@host_name[:port_num]/db_name/tbl_name';  ← 접속정보

참고 : https://dev.mysql.com/doc/refman/5.7/en/federated-create-connection.html

 

하지만, 이렇게 생성한 TABLE Script는

아래 명령을 사용해 확인할 수 있으며

CONNECTION에 입력한 접속정보까지 모두 표시된다.

 mysql> SHOW CREATE TABLE 테이블명;

 

(TEST용이 아니라면) 접속정보를 별도로 생성하는 것이 좋을 듯 하다.

 

 

2.2. 접속정보를 별도로 생성해서 TABLE 생성

 

 -- MySQL 접속

 # mysql -u root -p

 

 -- mysql database 사용

 mysql> USE mysql;

 

 -- 접속할 원격서버정보 추가

 mysql> CREATE SERVER 서버명

           FOREIGN DATA WRAPPER mysql

           OPTIONS ( HOST '접속할IP'
                        , DATABASE 'DB Schema명'
                        , USER '아이디'
                        , PASSWORD '비밀번호'
                        , OWNER '아이디'  ← 현재 미적용? 생략해도...
                        , PORT 3306 );

 

 -- 원격서버정보 조회

 mysql> SELECT * FROM servers;

 

 CREATE TABLE 테이블명 { ... }

 ENGINE=FEDERATED ...

 CONNECTION='생성한서버명/tbl_name';  ← 접속정보

참고 : https://dev.mysql.com/doc/refman/5.7/en/federated-create-server.html

 

 

이제 생성한 FEDERATED Table을 조회할 수 있다.

 

 

Oracle의 DB Link와 동일한 것을

MySQL에서 처리하는 방법이

 

DB Link시킬 원격테이블을

Local에 FEDERATED Engine을 사용한 TABLE로 생성하는 것이다.

 


1. 준비

 

*** Local DB ***

1.1. FEDERATED Engine 사용가능하도록 설정

 

1.1.1. MySQL에서 FEDERATED Engine 존재여부/상태 확인

 -- MySQL 접속

 # mysql -u root -p

 

 mysql> SHOW ENGINES;

 +--------------------+---------+
 | Engine               | Support |
 +--------------------+---------+
 | FEDERATED          | YES     |  ← 이렇게 표시되어야 준비된 것이다.
 +--------------------+---------+

 

1.1.2. FEDERATED Engine이 존재하지 않는다면?

 mysql> INSTALL PLUGIN federated SONAME 'ha_federated.so';

 

1.1.3. FEDERATED Support가 NO라면?

 # MySQL 설정파일에 FEDERATED Engine 지원 설정

 

 # sudo vi /etc/mysql/my.cnf

 

 [mysqld] 아래에 아래 단어 추가 후 저장
 federated

 # MySQL 서비스 재기동

 # /etc/init.d/mysql restart

 

※ 여기까지해서 FEDERATED Support가 YES 여야 한다.

 

 

*** (연결할) 원격 DB ***

1.2. 접속시킬 ID 생성/권한 설정

     ※ 다른 System에서 해당 ID를 사용하고 있다면,

        (TEST용이 아니라면) 전체 권한을 주기보다는

        접속할 IP와 접속 ID/비번을 별도로 지정하여 설정하는 것이 좋을 듯 하다.

 

 -- MySQL 접속

 # mysql -u root -p

 

 -- 접속할 ID 생성

 -- (지정한 IP에서만 접속을 사용할 수 있도록 제한한다.)

 mysql> CREATE USER '아이디'@'접속을시도하는DB의IP' IDENTIFIED BY '비밀번호';

 

 -- 생성한 ID에 TABLE 접근 권한 설정

 -- (해당 Schema의 모든 테이블에 접근할 때는 테이블명에 * 를 사용)

 -- (별도의 세부권한은 ALL 대신 쓸 수 있다...별도로 조사해야;;;)

 mysql> GRANT ALL PRIVILEGES ON DBSchema명.테이블명 TO 아이디@'접속을시도하는DB의IP';

 

 

mysql - DB Link, FEDERATED TABLE 생성 (2/2) - 생성

 

 

developer.apple.com에서 Membership 결제를 하는데...

국내 대행사이신 KG Inicis님께서...

 

크롬에서도 결제 안된다...

 

 

 

 

엣지도도 결제 안된다...

 

 

 

오로지 IE11로만 결제하라시니...

 

그런데... 이늠의 IE11 께서는... 제대로 표시가 안되니...;;;

뭐냐... win10 새로 설치해놓은 곳에서조차 제대로 실행이 안되고...

이리 저리 메뚜기하다... 겨우 겨우 결제를 하긴 했는데...

뭔 결제에 잃어버린 내 금쪽같은 시간들...!!!

 

아... 뭔가 아이러니에 오묘한 기분...;;;

이건 뭐지???  @.@;;;

 

 

+ Recent posts