2023. 12. 26.

커리어 3가지 원칙

  1. 당신이 사지 않을 것을 팔지 마라.
  2. 존경할 수 있는 사람과 일하라.
  3. 좋아하는 사람과 같이 일을 하라.
  1. Don't sell anything you wouldn't buy yourself.
  2. Don't work for anyone you don't respect and admire.
  3. Work only with people you enjoy.

2023. 2. 9.

스프링 부트 데이터베이스 초기화

2.5 버전부터 Hibernate 초기화 방식 변경사항으로 인한 오류와 설명을 보고 문서로 정리해 남기면 좋겠다는 생각이 들어 작성 (검색어는 'Hibernate and data.sql')

- 이제 기본적으로 data.sql 스크립트는 Hibernate 초기화 전에 실행
- 'Flyway'와 'Liquibase'라는 데이터베이스 마이그레이션 툴 동작과 일치시키기 위함
- 'data.sql'을 사용하기 위해서는 'spring.jpa.defer-datasource-initialization=true' 설정
- 'schema.sql' 스트립트 또한 사용할 수 있게 해준다.
- 데이터베이스 초기화 기술을 혼합해 사용하는 걸 권장하지 않는다.

출처: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql


스프링 부트 공식 문서 "How-to" 설명

9.3. SQL 스크립트를 사용해 데이터베이스 초기화
- 스크립트 기반 DataSource 초기화는 기본적으로 'JPA EntityManagerFactory Bean'이 생성되기 전에 수행
- 'schema.sql'을 사용해 JPA-관리 엔티티에 대한 스키마를 생성하고 'data.sql'을 사용해 데이터를 채울 수 있다.
- 여러 데이터 소스 초기화 기술을 사용하는 것을 권장하지 않지만
- 만약 Hibernate로 생성된 스키마를 스크립트 기반 데이터소스 초기화를 원한다면 'spring.jpa.defer-datasource-initialization=true' 설정
- 이렇게 하면 'EntityManagerFactory Bean'이 생성되고 초기화될 때까지 데이터 소스 초기화 지연

출처: https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.using-basic-sql-scripts


참고용 스프링 부트 공식 예제 PetClinic 'application.properties'

# database init, supports mysql too
database=h2
spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
spring.sql.init.data-locations=classpath*:db/${database}/data.sql

# JPA
spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=true

'data.sql' 예시

INSERT INTO vets VALUES (default, 'James', 'Carter');
INSERT INTO vets VALUES (default, 'Helen', 'Leary');
INSERT INTO vets VALUES (default, 'Linda', 'Douglas');

'schema.sql' 예시

DROP TABLE vet_specialties IF EXISTS;
DROP TABLE vets IF EXISTS;
DROP TABLE specialties IF EXISTS;

2023. 1. 17.

Apache Commons Net FTP 연결이 안될 때

연결을 시도해도 파일의 용량이 0이 되는 현상

사용법이 친절하게 설명된 게 아니라서 찾는데 애 좀 먹었었다. 초기에 모드에 대한 부분을 꼭 작성해야 한다.

// Use passive mode as default because most of us are
// behind firewalls these days.
if (localActive) {
    ftp.enterLocalActiveMode();
} else {
    ftp.enterLocalPassiveMode();
}
출처: https://commons.apache.org/proper/commons-net/
https://commons.apache.org/proper/commons-net/examples/ftp/FTPClientExample.java

import org.apache.commons.net.ftp.FTPClient;

public class FTP_Connector {
  public static void main(String args[]) throws IOException {
    FTPClient ftp_client = new FTPClient();
    ftp_client.enterLocalPassiveMode();
  }
}