Spring Boot JPA로 Entity 설계 시, 컬럼에 Null을 허용하지 않도록 설정하기 위해
@NotNull 또는 @Column(nullable = false) 을 사용합니다.
이 둘의 차이점에 대해 간략하게 정의하고자 합니다.
Spring JPA에서 제공되는 이노테이션으로 Entity의 컬럼을 지정합니다.
이 때, 아래의 속성들을 지정할 수 있습니다.
JSR-303/JSR-349 Bean Validation
Spring Framework 4.0 supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1 (JSR-349) in terms of setup support, also adapting it to Spring’s Validator interface.
An application can choose to enable Bean Validation once globally, as described in Section 7.8, “Spring Validation”, and use it exclusively for all validation needs.
An application can also register additional Spring Validator instances per DataBinder instance, as described in Section 7.8.3, “Configuring a DataBinder”. This may be useful for plugging in validation logic without the use of annotations.
Spring Framework 4.0부터 지원되는 Bean Valication입니다.
주로 Spring의 Validator가 유효성 검증을 수행할 때 사용되는 이노테이션입니다.
@Column(nullable = false)로 설정하는 것은 Entity 컬럼의 null 허용 여부를 설정하는 것이고,
@NotNull은 Java Bean의 null 유효성 검증을 위한 설정입니다.
즉, 위 2개의 이노테이션은 사용 목적이 다릅니다.
@Entity
public class Test {
@Id
private int id;
@Column(nullable = false)
private String name;
}
Entity와 Table의 DDL에 NOT NULL로 설정되고 DB에 Null 값을 입력 할 때 오류가 발생합니다.
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null];
@Entity
public class Test {
@Id
private int id;
@NotNull
private String name;
}
Entity의 유효성 검증 시 오류가 발생합니다.
ConstraintViolationImpl{interpolatedMessage=’널이어서는 안됩니다’, propertyPath=name, rootBeanClass=class
@Column(nullable = false)은 DB에 제약조건을 거는 것이고,
@NotNull은 유효성 검사를 수행하는 것입니다.
hibernate는 @NotNull가 설정되어 있으면 자동으로 DB에 제약조건을 추가해줍니다.
@NotNull = @Column(nullable = false) + 유효성 검사
Spring에서 LocalDateTime을 JSON으로 변환 시 Array 형태로 표출 되는 현상이 발생하였습니다.
{
"id": 1,
"name": "test",
"createdAt": [
2023,
7,
27,
15,
47,
7,
972737100
],
"updatedAt": [
2023,
7,
27,
15,
47,
7,
972737100
]
}
Spring 2.0.0이상의 버전에서는 데이터 반환 시 별다른 설정을 하지 않아도 LocatDateTime의 값을 String 으로 자동으로 변환하여 반환합니다.
이는 jackson-datatype-jsr310가 기본적으로 포함되어 있어 있기 때문입니다.
Add-on module to support JSR-310 (Java 8 Date & Time API) data types.
하지만, EnableWebMvc를 설정하면 Springd은 자체적으로 기본적인 ObjectMapper를 구성하게 됩니다.
이로 인해 직렬화와 관련된 설정들이 변경될 수 있으며, 사용자 정의 설정이 무시될 수 있습니다.
(Spring 2.7.0 기준)
Spring이 WebMvcConfigurerAdapter 클래스를 자동으로 등록할 때, configureMessageConverters 메서드를 재정의하고. 이 때 jackon-datatype-jar310이 적용되지 않는 것으로 추측됩니다.
이러한 문제를 해결하기 위해서는 해당 필드에 JsonFormat를 지정하거나, ObjectMapper를 등록 또는 재정의하는 방법이 있습니다.
@JsonFormat(shape = JsonFormat.Shape.STRING,
pattern = "yyyy/MM/dd'T'HH:mm:ss")
private LocalDateTime createdAt;
간단하게 적용 할 수 있는 장점이 있지만, 매번 필드에 정의 해줘야 하는 불편함이 있습니다.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(customObjectMapper());
converters.add(converter);
}
@Bean
public ObjectMapper customObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// 여기에 원하는 ObjectMapper 설정을 추가할 수 있습니다.
return objectMapper;
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(mappingJackson2HttpMessageConverter());
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.dateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
return new MappingJackson2HttpMessageConverter(builder.build());
}
}
MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand.
MapStruct는 Java bean 유형 간의 매핑 구현을 단순화하는 코드 생성기입니다.
Spring에서는 interface를 정의하고 @Mapper 이노테이션을 달아주면, 간단하게 코드를 자동 생성시키고 이를 bean으로 등록시킵니다.
@Mapper
public interface TestMapper {
TestMapper MAPPER = Mappers.getMapper(TestMapper.class);
}
위의 TestMapper 코드에 변환하고자 하는 Java bean 유형을 정의하여 사용하면 됩니다.
Mapstruct는 매핑 구현 코드를 자동으로 생성 할 때, 변환하고자 하는 Java bean 유형의 생성자 또는 builder 를 사용하여 구현됩니다.
id와 name 필드를 가지는 Entity입니다.
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true)
public class TestEntity {
int id;
String name;
@Builder
public TestEntity(String name) {
this.name = name;
}
}
DTO를 Entity로 변환하는 맵퍼입니다.
@Mapper
public interface TestMapper {
TestMapper MAPPER = Mappers.getMapper(TestMapper.class);
TestEntity toEntity(TestDto dto);
}
생성자에 지정된 필드를 기준으로 매핑 구현 코드가 생성 됩니다.
public class TestDto {
private String name;
public TestDto(String name) {
this.name = name;
}
}
public class TestMapperImpl implements TestMapper {
public TestEntity toEntity(TestDto dto) {
if (dto == null) {
return null;
}
String name = null;
name = dto.getName();
TestEntity testEntity = new TestEntity(name);
return testEntity;
}
}
위 코드를 빌드하면 아래와 같은 경고 가 발생합니다.
Task :compileJava
mapper\EntityMapper.java:4: warning: Unmapped target property: “id”.
TestEntity toEntity(TestDto dto);
1 warning
TestEntity의 id 필드와 팹핑되는 필드가 없어서 발생하는 경고입니다.
이를 해결하기 위해 Mapping 시 id를 매핑하지 않도록 설정합니다.
@Mapper
public interface TestMapper {
TestMapper MAPPER = Mappers.getMapper(TestMapper.class);
@Mapping(ignore = true, target = "id")
TestEntity toEntity(TestDto dto);
}
정의된 Builder 메소드를 통해 매핑 구현 코드가 생성 됩니다.
public class TestDto {
private String name;
@Builder
public TestDto(String name) {
this.name = name;
}
}
public class TestMapperImpl implements TestMapper {
public TestEntity toEntity(TestDto dto) {
if (dto == null) {
return null;
}
TestEntityBuilder testEntity = TestEntity.builder();
testEntity.name(dto.getName());
return testEntity.build();
}
}
빌드 패턴을 사용하면, 위의 “warning: Unmapped target property”가 발생하지 않습니다.
(Mapstruct는 builder가 모든 필드를 맵핑한 것으로 판단하는 것 같습니다.)
Lombok의 @builder로 빌드 패턴을 사용 시,
annotationProcessor의 순서는 mapstruct-processo가 lombock보다 앞에 정의 되어야 합니다.
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"
annotationProcessor "org.projectlombok:lombok:1.18.20"
annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
Software architecture를 표현하기 위한 다양한 방법들이 있지만, 저는 시스템을 분석 및 설계할 때 주로 아래의 문서를 작성합니다.
초기에는 Microsoft PowerPoint로 모든 아키텍처를 표현했었습니다.
단순한 시스템 구성도에서부터 다양한 다이어그램까지(시퀀스 다이어그램, 액티브 다이어그램, ERD 등), 거의 모든 문서를 MS PowerPoint 하나로 해결 할 수 있었습니다.
(물론 지금도 가장 많이 사용하고 있는 도구 중 하나입니다.)
MS PowerPoint는 분명 만능의 도구이지만, 그 만큼 자유도가 높아 매번 다른 스타일의 문서가 생성되었고, 지속적으로 관리가 되지 않았습니다.
이러한 설계 문서는 작성하는 것도 중요하지만, 관리도 매우 중요합니다.
보통 시스템 분석 및 설계 시 열심히 작성해 놓고, 그 이후에는 잘 보지 않는 경우가 많았습니다.
왜냐하면 초기 설계 이후로 변경된 내용들을 지속적으로 갱신 하지 않았기 때문입니다.
좀 더 체계적으로 사용할 수 있는 방법을 찾아보며 다양한 도구들을 사용해보았습니다.
그러다 최근 정착하게 된 도구가 plantuml입니다.
PlantUML은 사용자가 일반 텍스트 언어로 다이어그램을 작성할 수 있는 오픈 소스 도구입니다.
일반 텍스트 언어로 작성하기때문에 기존에 사용 중인 소스 형상 관리 도구에 그대로 적용 할 수 있습니다.
예를 들어, Git과 같은 형상 관리 서버의 해당 프로젝트 내에서 설계 문서를 함께 관리 할 수 있습니다.
또한, 다양한 다이어그램을 작성 할 수 있어 설계 문서의 양식을 통일 할 수 있습니다.
C4 Model은 소프트웨어 시스템의 아키텍처를 모델링하기 위한 그래픽 표기법 중 하나로,
UML과 4+1 아키텍처 뷰 모델을 기반으로
시스템을 계층 수준에 따라 시각적으로 표현하고 이를 문서화합니다.
Level 1 : 범위 내 시스템과 사용자 및 다른 시스템과의 관계(=System Diagram)
Level 2 : 시스템을 상호 관련된 컨테이너로 분해(=Container Diagram)
Level 3 : 컨테이너를 상호 관련된 구성 요소로 분해(=Component Diagram)
Level 4 : 코드에 맵핑 할 수 있는 수준으로 분해(=Code Diagram)
C4-PlantUML은 PlantUML로 다이어그램을 생성하기 위한 매크로로 스트레오타입 등이 정의되어 있습니다.
(PlantUML이 제공되는 다이어그램에 C4 Model 스타일을 적용)
지원되는 다이어그램 목록 :
QGroundControl 소스 코드를 가져와 기본적으로 빌드하는 방법을 설명합니다.
$ git clone --recursive -j8 https://github.com/mavlink/qgroundcontrol.git
QGC(2023.06.19, qgc v4.2.6)는 QT 5.15.2를 대상으로 테스트되었으며, 그외 버전은 정식으로 지원하지 않습니다.
Do not use any other version of Qt! QGC has been thoroughly tested with the specified version of Qt (5.15.2). There is a significant risk that other Qt versions will inject bugs that affect stability and safety (even if QGC compiles).
Linux Conntainer 이미지로
제공되는 Docker 파일을 이용하여 별도의 설치 없이 빌드 및 배포를 수행 할 수 있습니다.
(해당 Docker 파일은 Ubuntu 20.04로 구성되어 있습니다.)
To install :
> cd qgroundcontrol
> docker build --file ./deploy/docker/Dockerfile-build-linux -t qgc-linux-docker .
shell
$ cd qgroundcontrol
shell
> docker run --rm -v ${PWD}:/project/source -v ${PWD}/build:/project/build qgc-linux-docker
macOS, Linux, Windows, iOS 및 Android의 빌드를 지원합니다.
윈도우 환경에서는 Visual Studio 2019 Compiler(64bit)로 컴파일을 수행합니다.
Desktop development whth C++를 선택하여 설치를 진행합니다.

The Qt Company offering changes, open source offline installers are not available any more since Qt 5.15. Read more about offering changes in the https://www.qt.io/blog/qt-offering-changes-2020 blog. If you need offline installers, please consider our new Qt for Small Business offering: https://www.qt.io/blog/available-now-qt-for-small-businesses
$ ./qt-unified-linux-x64-4.6.0-online.run

기본적으로 최신 버전만 선택할 수 있습니다.
Archive를 체크 후 Filter 버튼을 클릭하여 이전 버전을 불러옵니다.

CLI에서 qmake를 사용하여 빌드
1) 다운로드한 레포짘토리 폴더로 이동
$ cd qgroundcontrol
2) 빌드를 수행한 디렉토리를 생성하고 이동
$ mkdir build
$ cd build
3) qmake 스크립트를 사용하여 빌드 구성
$ qmake ../
4) make를 실행하여 컴파일(-j{number of threads} )
make -j12
$ ./staging/QGroundControl
$ vi /usr/lib/x86_64-linux-gnu/qtchooser/qt5.conf
/opt/QT/5.15.2/gcc_64/bin
/usr/lib/x86_64-linux-gnu
ompiling /home/ubuntu/Documents/qgroundcontrol/src/QGCToolbox.cc
In file included from /home/ubuntu/Documents/qgroundcontrol/src/Airmap/AirMapSharedState.h:17,
from /home/ubuntu/Documents/qgroundcontrol/src/Airmap/AirMapManager.h:12,
from /home/ubuntu/Documents/qgroundcontrol/src/QGCToolbox.cc:38:
/home/ubuntu/Documents/qgroundcontrol/src/Airmap/services/client.h:4:10: fatal error: airmap/client.h: No such file or directory
4 | #include <airmap/client.h>
| ^~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:260800: QGCToolbox.o] Error 1
07:52:49: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project qgroundcontrol (kit: Desktop Qt 5.15.2 GCC 64bit)
When executing step "Make"
This currently applies to Airmap on Linux, which is optional but enabled by default.
airmap을 비활성화 합니다.
$ echo -e "DEFINES += DISABLE_AIRMAP\r\n" | tee user_config.pri
ATM / UAM / UTM 서비스를 위해 사용되는 용어를 정리하고 있습니다.
아직 미정립되거나 개념을 수립 중인 용어도 포함 되어 있습니다.
| Acronym | Definition | 정의 |
|---|---|---|
| AAM | Advanced Air Mobility | 첨단 항공 모빌리티 |
| AFR | Automated Flight Rule | 자동 비행 규칙 |
| ASM | Air Space Management | 항공역 관리 |
| ATC | Air Traffic Control | 항공 교통 관제 |
| ATS | Air Traffic Service | 항공 교통 서비스 |
| CA | Cooperative Ares | 협동 구역 |
| CEP | Corridor Entry/Exit Point | 회랑 입출점 |
| CFM | Cooperative Flow Management | 협력 흐름 관리 |
| CNS | Communication, Navigation, and Surveillance | 통신, 안내, 감시 |
| COP | Cooperative Operating Practice | 협력 운영 관행 |
| ConOps | Concept of Operations | 운영의 개념 |
| DCB | Demand-Capacity Balancing | 수요-용량 균형 |
| DEP | Distributed Electric Propulsion | 분산 전기 추진 |
| DOT | Department of Transportation | 교통(부)과 |
| EDCT | Expect Departure Clearance Time | 예상 출발 허가 시간 |
| ETM | Upper Class E Traffic Management | 상부 등급E 교통관리 |
| eVTOL | Electric Vertical Takeoff and Landing | 전기추진 수직 이착륙기 |
| FAA | Federal Aviation Administration | 미연방항공청 |
| FIS | Flight Information Service | 항공 정보 서비스 |
| IFR | Instrument Flight Rules | 계기비행 규칙 |
| IMC | Instrument Meteorological Conditions | 계기비행 기상 조건 |
| LOA | Letter of Agreement | 합의서 |
| NAS | National Airspace System | 국가 공역 체계 |
| NASA | National Aeronautics and Space Administration | 미항공우주국 |
| NOTAM | Notice to Air Missions | 항공 임무 공지 |
| PIC | Pilot in Command | 조종사 |
| PSU | Provider of Services for UAM | UAM 서비스 제공자 |
| RPIC | Remote Pilot in Command | 원격 조종사 |
| SAA | Special Activity Airspace | 특수 활동 공역 |
| SDSP | Supplemental Data Service Provider | 부가 데이터 서비스 제공자 |
| TFM | Traffic Flow Management | 교통 흐름 관리 |
| TFR | Temporary Flight Restriction | 임시 비행 제한 |
| UAM | Urban Air Mobility | 도심 항공 모빌리티 |
| UAO | UAM Air Operator | UAM 이해 관계자 |
| UATM | UAM Air Traffic Management | UAM 교통 관리 |
| UAS | Unmanned Aircraft Systems | 무인 항공기 시스템 |
| USS | UAS Service Supplier | UAS 서비스 공급자 |
| UTM | UAS Traffic Management | UAS 교통 관리 |
| V2V | Vehicle-to-Vehicle | 차량 to 차량 |
| VFR | Visual Flight Rules | 시계비행 규칙 |
| VMC | Visual Meterological Conditions | 시계비행 기상 조건 |
| VPO | VertiPort Operator | 버티포트 이해관계자 |
| VTOL | Vertical Takeoff and Landing | 수직이착률 |
| xTM | Extensible Traffic Management | 확장가능한 교통 관리 |