묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! FastAPI 입문
'Session' object has no attribute 'scalars' 오류 발생합니다.
강사님 안녕하세요. 파이썬 콘솔에서는 list(session.scalars(select(ToDo))) 이 코드가 잘 실행되었는데, main.py 코드 모두 작성 후 스웨거에서 get /todos 에서 실행하면,터미널에 AttributeError: 'Session' object has no attribute 'scalars'오류가 뜹니다. ㅠㅠ
-
해결됨실전! FastAPI 입문
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") 오류
OS: macOSpython 3.10 버전을 사용하고 있고,sqlalchemy 2.0.19, pymysql 1.1.0 등등 최신 패키지 사용중입니다.from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker DATABASE_URL = "mysql+pymysql://root:todos@127.0.0.1/todos" engine = create_engine(DATABASE_URL, echo=True) SessionFactory = sessionmaker(autocommit=False, autoflush=False, bind=engine) connection.py 는 위와 같이 동일하게 작성했고,session.scalar(select(1)); 실행시 아래와 같은 오류가 발생하여 더 이상 진행을 할 수가 없습니다.Traceback (most recent call last): File "/Users/someone/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/232.8660.197/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode coro = func() File "<input>", line 1, in <module> File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2296, in scalar return self._execute_internal( File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2131, in _execute_internal conn = self._connection_for_bind(bind) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1998, in _connection_for_bind return trans._connection_for_bind(engine, execution_options) File "<string>", line 2, in _connection_for_bind File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go ret_value = fn(self, *arg, **kw) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1123, in _connection_for_bind conn = bind.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3264, in connect return self._connection_cls(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 147, in __init__ Connection._handle_dbapi_exception_noconnection( File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2426, in _handle_dbapi_exception_noconnection raise sqlalchemy_exception.with_traceback(exc_info[2]) from e File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 145, in __init__ self._dbapi_connection = engine.raw_connection() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3288, in raw_connection return self.pool.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 452, in connect return _ConnectionFairy._checkout(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 1267, in _checkout fairy = _ConnectionRecord.checkout(pool) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 716, in checkout rec = pool._do_get() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 169, in _do_get with util.safe_reraise(): File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 147, in __exit__ raise exc_value.with_traceback(exc_tb) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 167, in _do_get return self._create_connection() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 393, in _create_connection return _ConnectionRecord(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 678, in __init__ self.__connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 902, in __connect with util.safe_reraise(): File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 147, in __exit__ raise exc_value.with_traceback(exc_tb) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 898, in __connect self.dbapi_connection = connection = pool._invoke_creator(self) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/create.py", line 637, in connect return dialect.connect(*cargs, **cparams) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 615, in connect return self.loaded_dbapi.connect(*cargs, **cparams) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 358, in __init__ self.connect() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 664, in connect self._request_authentication() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 976, in _request_authentication auth_packet = _auth.caching_sha2_password_auth(self, auth_packet) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/_auth.py", line 267, in caching_sha2_password_auth pkt = _roundtrip(conn, data) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/_auth.py", line 120, in _roundtrip pkt = conn._read_packet() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/connections.py", line 772, in _read_packet packet.raise_for_error() File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error err.raise_mysql_exception(self._data) File "/Users/someone/.pyenv/versions/fastapi-env/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception raise errorclass(errno, errval) sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") (Background on this error at: https://sqlalche.me/e/20/e3q8) Check the PassWord Hashing Method: If the MySQL server is using caching_sha2_password but the client (like PyMySQL) doesn't support it, it can give rise to such issues. You can switch the MySQL user's password hashing method to mysql_native_password.이런 글도 있어서 따라하고 새로 비밀번호를 todos 로 넣어줬는데도 마찬가지네요. 더 참고할만한 내용이 있을까요?
-
해결됨실전! FastAPI 입문
백엔드 구축관련
안녕하세요 본 강의 완강후 백엔드 구축이 가능한지요?
-
해결됨실전! FastAPI 입문
AssertionError: Expected 'undone' to be called once. Called 0 times.
def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") mocker.patch( "main.update_todo", return_value=ToDo(id=1, contents="todo", is_done=False), ) # API 호출 여부 response = client.patch("/todos/1", json={"is_done": False}) undone.assert_called_once_with() assert response.status_code == 200 # 성공 assert response.json() == {"id": 1, "contents": "todo", "is_done": False} # 성공 # Resetting the mock before the next scenario # 404 mocker.patch( "main.get_todo_by_todo_id", return_value=None, ) response = client.patch("/todos/1", json={"is_done": True}) assert response.status_code == 404 assert response.json() == {"detail": "ToDo Not Found"} pytest 시 아래와 같은 에러가 발생합니다. 강사님 코드와 상이한 부분도 없고 로직도 맞게 작성한 것 같은데 undone이 한번도 호출이 되지 않았다고 합니다.During handling of the above exception, another exception occurred: client = <starlette.testclient.TestClient object at 0xffff89948640>, mocker = <pytest_mock.plugin.MockerFixture object at 0xffff89004e50> def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") > print(undone.assert_called_once_with()) E AssertionError: Expected 'undone' to be called once. Called 0 times. tests/test_main.py:106: AssertionError ========================================================== short test summary info ========================================================== FAILED tests/test_main.py::test_update_todo - AssertionError: Expected 'undone' to be called once. Called 0 times. ======================================================== 1 failed, 5 passed in 0.18s ======================================================== #
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요! @Nullable 관련해서 질문이 있습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.이번 강의에서 플랫폼 타입으로 인해 Java 와 Kotlin 간에 발생할 수 있는 문제점을 설명해주셨는데요.특히, 아래의 코드를 테스트할 때 null 때문에 발생할 수 있는 문제점과 해결할 수 있는 방법을 설명해주셨습니다.assertThat(results[0].age).isNull()Java 클래스의 getter에 @Nullable을 붙여줌으로써 해결할 수 있었는데요.제가 궁금한 것은 롬복의 @Getter가 클래스 레벨에서 적용된 경우에는 어떻게 @Nullable을 붙여줄 수 있느냐가 궁금했습니다.코틀린으로 변환 과정에서 롬복의 @Getter가 만들어주는 게터들을 모두 하드 코딩으로 작성하고 나서 @Nullable 어노테이션을 해당하는 게터에 달아줘야하는건지, 아니면 더 좋은 방법이 있는지 궁금합니다!모든 클래스가 그렇지는 않겠지만 아무래도 기존에 사용하고 있던 자바 클래스 코드들에 @Getter 어노테이션이 달려 있을 것이라고 예상이 되고 이 경우에는 어떻게 테스트 해당 문제를 해결해야하는지 궁금하네요더불어 좋은 강의 감사합니다!
-
해결됨실전! FastAPI 입문
Depends() 안에 callable한 것을 넣는 경우와 안 넣는 경우
4:24 초에 user_repo: UserRepository = Depends()이런 식으로 여기서는 Depends() 안에 아무것도 넣어주지 않는데, 그냥 Depends() 자체만으로는 어떤 의미가 있나요?
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요 강사님 도메인 생성 시 주 생성자에 관한 질문드립니다.
안녕하세요 강사님~ 강의 너무 재밌게 잘 보고 있습니다.강의중에 User 리팩토링 과정에서 userLoanHistories를 주생성자에 선언하셨는데@Entity class User( @Column(nullable = false) var name: String, val age: Int?, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, ) { // 클래스 바디로 내려도 되나요? @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true) val userLoanHistories: MutableList<UserLoanHistory> = mutableListOf() (...) }기존 자바코드에서는 이 컬랙션은 내부적으로 사용될뿐 getter로 접근하는 부분이 없기에 굳이 주생성자에 선언하는 것보다 클래스 바디로 내리는게 뭔가 더 자연스럽지 않나 하여 질문드렸습니다..!
-
해결됨실전! FastAPI 입문
(실습) MySQL 컨테이너 실행
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=todos -e MYSQL_DATABASE=todos -d -v todos:/db -–name todos mysql:8.0터미널에서 위 명령어 실행하면,docker: Invalid containerPort: 3306 -e.이런 오류가 발생합니다. ㅠㅠ 참고로 docker 처음 써보는 초급입니다.
-
미해결은종쌤과 자바로 디자인 패턴 쉽게 시작하기
Strategy 패턴 예시 질문드립니다
Strategy 패턴 예시에서showGradeInfo 의 gradeEvaluation을 Factory로 구현하면 Factory 패턴 인가요 Strategy패턴인가요..?
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
.
.
-
해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
재활용 극대화를 위한 상속구조 + Mixin(!?) 구성에 대한 질문입니다.
한 3일동안 산넘고 물건너 아직 끝이 어딘지도 모르고 해매고 있습니다 ㅎㅎ 안녕하세요 강사님.상황:제목에서도 알 수 있듯, Kotlin Jpa Mixin 을 소개하는 글로 부터 힌트를 얻고, 소스코드:BitBucket 자료를 참고삼아 강의 16강 정도의 예제를 업그레이드 하고 강의를 계속 이어가려다, 돌부리에 걸려 자빠져 입원한듯, 강의를 이어갈수 없게 지체되어서 몇일째 끙끙 앓고있답니다. 제가 참고한 자료 자체가 너무 오래된 5년전 자료라, 최신자료를 찾아봐도 찾아지지 않아서 이 예제를 참고했는데, 이것조차 유효한 자료인지 가늠이 안되었지만 이걸 변형해서라도 조립형태로 가야겠다는 목표가 생겨서 이 가이드를 응용하기로 했습니다..Kotlin 에서 지원하는 Mixin 기법(맞는지 모르겠습니다)을 도전하게 되었어요. 엔티티, 테이블 모두 생성은 되는데, Mixin 속성은 적용이 안되어서, 테이블을 보면 덩그러니 ID 만 보입니다. 원인과 관련 자료가 너무 없어서 관둬야 하나... 하다가 핼프요청 하게 되었어요.제가 16강 예제와 와 위에 Mixin 예제로 재구성한 제 Gist(entities.kt) 를 보시면 아시겠지만 구조를 보여드리면 이렇습니다.entities.kt다이어그램:아래는..조립의 끝단에 있는 @Entity AuditableTestEntity 코드입니다./* Implementation */ @Entity class AuditableTestEntity constructor( name: String, age: Int?, ) : Identifier<Long>(), AccessTimeAuditable by AccessTimeAudit(), AccessorAuditable by AccessorAudit(), Nameable by Named(name), Ageable by Aged(age) 코드를 보면 위의 부품(인터페이스 by 구현체)들이 조립된 형태로 되어있습니다. 컴파일에도 문제가 없어 잘 되는가 싶었지만, [컴파일> 서버 기동] 이후 결과는 다음과 같습니다.DB 테이블 상황ID를 제외한 나머지(name, age, created..., 등) 속성이 전혀 반영이 안되었지요. 아래는 서버 구동시 테이블 생성 쿼리 로그입니다.Hibernate: create table auditable_test_entity ( id bigint generated by default as identity, primary key (id) )질문:@MappedSuperclass 를 @Entity 를 제외한 모든 클래스에 붙여도 보고, 필드용 에노테이션 역시 Interface 로 옮겨도 보고, Use-site (@get, @filed 등)를 붙여옮봐도, 인식이 안되는건 여전하더라구요. 그래서 혹시 이방식이 동작하지 않는 원인이라던지, Kotlin 설정이나 플러긴 버전의 차이 같은 누락 요인이라던지, 더 나은 방식이 있다면 조언을 얻고자 질문하게 되었습니다. 읽어주셔서 감사합니다.
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
코틀린 JPA 질문이 있습니다
안녕하세요.Sto라는 부모 엔티티가 있습니다.자식으로는 Realestate 라는 엔티티가 있습니다.해당 엔티티의 관계는 Sto + Realestate 이렇게 1개의 쌍을 이루어 생성이 됩니다.저는 @OneToOne 양뱡향 관계를 사용하고 있습니다.cascade 속성을 이용하여, Sto를 save 했을 때 하위 엔티티까지 함께 저장하려고 하고 있습니다.이때, 모든 엔티티를 val를 사용하려고 했는데 Sto 생성자 호출 시 하위 엔티티에서 Sto 엔티티의 값을 알 수가 없어서 생성이 불가한 상태입니다.물리적으로 Sto + Realestate는 한쌍인데 방법이 없을까 싶어 문의드립니다.var + null을 사용하면, 어떻게든 할 수 있을 것 같은데 양방향 설정을 위해 이렇게 풀어서 사용해야 하나 궁금하네요..@Entity @Table(name = "sto") class Sto( @Id @Column(name = "sto_id", nullable = false) private val id: String, @OneToOne( mappedBy = "sto", cascade = [CascadeType.PERSIST] ) val realestate: Realestate, @OneToOne( mappedBy = "sto", cascade = [CascadeType.PERSIST] ) val youtube: Youtube, ) @Entity class Realestate( @Id @Column(name = "realestate_id", nullable = false) private val id: String, @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "sto_id", nullable = false) val sto: Sto, ) fun main() { Sto( id = "sto_id", realestate = Realestate( id = "realestate_id", sto = 여기가 문제네요.. ) ) }
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요 강사님
개인적으로 공부를 하던 중 잘 풀리지 않아 문의드리게 되었습니다.java.kt다름이 아니라 실행시점에 샘플 데이터를 미리 저장시켜두고 싶어서 자바로 작성했던 위의 코드를 아래와 같이 코틀린으로 변경 후에 실행을 시켜보았습니다.그런데 실행을 시키면CGLIB, subclass 등 오류가 발생해서 구글 검색을 통해 최대한 해결해보려 하였으나, allOpen 설정도 해보고 이것저것 해보았음에도 해결하지 못해서 이렇게 염치불구하고 문의드리게 되었습니다 ㅜ 혹시 어떤 문제인지 아실까요??
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
build.gradle 파일 설정 질문
그래이들 설정 파일에 코틀린 라이브러리를 추가하는과정에 있어서 질의응답의 답글에 있는 레퍼런스를 참고하는 과정에 있어 특정 문단을 이해하기가 어려워 질문드립니다. 다음 레퍼런스를 참고 하였으며https://docs.spring.io/spring-boot/docs/3.1.1/reference/pdf/spring-boot-reference.pdf 7.11.1. Requirements 해당 세션에 있는 내용입니다.Since Kotlin classes are final by default, you are likely to want to configure kotlin-spring plugin inorder to automatically open Spring-annotated classes so that they can be proxied. 해당 부분입니다. 추가적으로 레퍼런스에서는 org.jetbrains.kotlin:kotlin-stdlib 및 org.jetbranins.kotlin:kotlin-reflect 가 클래스 패스에 존재햐아 한다는데, stdlib만 설정하신 이유도 궁금합니다.
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
assertThat import 문제
안녕하세요 강의를 진행하던 도중 assertThat의 import가이런 식으로 hamcrest의 import만 존재하는 이유가 무엇일까요?수동으로 import를 작성하면 문제없이 진행은 되고 있습니다.인터넷에 찾아보니 testImplementation 'org.assertj:assertj-core:3.20.2'을 추가하라는데 이미 spring-boot-start-test에 포함되어있어 문제는 없어보입니다.인텔리제이의 오류일까요?감사합니다!
-
해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
빌드 도구를 Gradle이 아닌 IntelliJ로 했을 때의 인식 오류(해결)
안녕하세요.강의 코드를 작성하던 도중 QUser 클래스가 UserRepositoryCustomImpl에서 인식이 되지 않는 오류가 발생하였습니다. 빌드도 다시 해보고, build 파일을 삭제하고 다시 빌드 해보고, 캐시도 삭제해봤는데도 인식이 안되길래, 혹시나 해서 설정에서 '다음을 사용하여 빌드 및 실행' 부분을 Gradle로 바꾸어주니 바로 인식이 되더라구요. 혹시나 저와 같은 상황에서 삽질하고 계신 분들을 위해 글 남깁니다 ㅎㅎ자세히 다시 읽어보니 일부 플러그인을 사용 시에 제대로 빌드가 되지 않을 수 있다고 적혀있네요..
-
해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
예외 처리 리팩토링 질문
안녕하세요.강의 들으며 재밌고 공부하고 있습니다. 감사합니다.예외 처리를 util패지키에 모아서 처리하는 것은 이해했습니다. 약간 궁금증 생겨서 문의 남겨봅니다!BookService의 코드 일부분 입니다. 여기서 보면 UserRepository와 BookRepository의 findByName에서 모두 fail()로 예외 처리를 하는데요, 이걸 그냥 리포지토리 계층의 메서드 자체에서 예외를 처리해주면 더 깔끔하지 않을까 하는 궁금증이 생겼습니다. 제가 지금까지 공부하면서는 리포지토리 계층에서 디폴트 메서드를 통해서 처리하는 코드도 봤고, 서비스 계층에서 처리하는 코드도 봐서 어떤 방식을 선호하시는지, 권장 하시는지 궁금합니다! 좋은 강의 감사합니다!
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
갑자기 test시 Build Failed이 발생합니다
안녕하세요.15강까지 강의를 듣고서 강사님처럼 마지막에 전체 테스트를 돌렸더니다음과 같이 빌드가 실패합니다 제가 뭘 잘못한걸까요? ㅜ
-
해결됨실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
assertThat import 문제
assertThat import 안되는 문제선생님 안녕하세요. 이번에 새로 수강하고 있는 수강생입니다.프로젝트 다운 받고 실행을 시켜려고 하는데 실행이 안돼서 따로 설정해서 돌리고 있습니다.Junit5까지는 진행했지만 assertThat 코드를 호출하는 진도에서 실행이 안되고 있습니다.혹시 어떤 방법으로 해결 할 수 있을까요? 찾아도 안나오네요 ㅠㅜbuild.gradle.kts 파일입니다import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "3.0.6" id("io.spring.dependency-management") version "1.1.0" id("java") id("org.jetbrains.kotlin.plugin.jpa") version "1.7.22" // id("org.jetbrains.kotlin.plugin.spring") version "1.7.22" id("org.jetbrains.kotlin.kapt") version "1.7.22" kotlin("jvm") version "1.7.22" kotlin("plugin.spring") version "1.7.22" } group = "com.example.kotlin" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_17 configurations { compileOnly { extendsFrom(configurations.annotationProcessor.get()) } } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.22") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3") implementation("org.junit.jupiter:junit-jupiter:5.8.1") implementation("com.querydsl:querydsl-jpa:5.0.0") kapt("com.querydsl:querydsl-apt:5.0.0:jpa") kapt("org.springframework.boot:spring-boot-configuration-processor") runtimeOnly("com.h2database:h2") testImplementation("org.assertj:assertj-core:3.21.0") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web-services") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") developmentOnly("org.springframework.boot:spring-boot-devtools") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation(kotlin("test")) } tasks { test { useJUnitPlatform() } withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "17" } } withType<Test> { useJUnitPlatform() } }
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
강사님 안녕하십니까 코틀린 var 선언에 대해서 질문이 있습니다.
var 를 선언하게 되면 setter 를 사용한 것 처럼 외부에서도 클래스 내부 필드에 접근하게 되어 캡슐화가 되지 않아서 setter 를 막아주고 싶습니다. 만약 그렇게 하고싶다면 모든 필드에 private set 을 선언해야할 것 같은데 중복코드의 느낌도 있고, 코틀린의 간결함이랑 멀어진다는 생각이 들었습니다. 보통 실무에서는 도메인, jpa 엔티티를 분리하는 방법이 아닌 set 을 막으려면 어떻게 처리를 하는지 궁금합니다.