Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
2fcff25
feat: ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„
YoungseoChoi23 Oct 23, 2025
69a95f8
merge with develop
YoungseoChoi23 Oct 24, 2025
037c057
merge with develop
YoungseoChoi23 Oct 24, 2025
1ce2f21
Fix : User ์—”ํ‹ฐํ‹ฐ์— tenant id ์ถ”๊ฐ€
YoungseoChoi23 Oct 24, 2025
09bf225
fix: organization ๋„๋ฉ”์ธ ๊ฒฝ๋กœ ์ˆ˜์ •
YoungseoChoi23 Nov 9, 2025
313c3fd
fix: gitguardian ํŒจ์Šค์›Œ๋“œ ํ•˜๋“œ์ฝ”๋”ฉ ์ˆ˜์ •
YoungseoChoi23 Nov 9, 2025
61a188b
refactor: BaseEntity JavaDoc ๊ฐœ์„ , Lombok(Getter, Setter) ์–ด๋…ธํ…Œ์ด์…˜ ์ ์šฉ
YoungseoChoi23 Nov 9, 2025
4418462
refactor: TenantAwareEntity ํ•„๋“œ, ๋ฉ”์„œ๋“œ JavaDoc ์ถ”๊ฐ€, Lombok(Getter, Setteโ€ฆ
YoungseoChoi23 Nov 9, 2025
ad40d7e
refactor: TenantAwareEntityListener ๋ฉ”์„œ๋“œ JavaDoc ์ƒ์„ธํ™”, ๋กœ๊ทธ ๋ฉ”์‹œ์ง€ ํ•œ๊ธ€ํ™”
YoungseoChoi23 Nov 9, 2025
77c6c4a
refactor: BaseRepository JavaDoc ๋ณด์™„, see ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€, ์ธ๋ผ์ธ ์ฃผ์„ ๋ณด์™„
YoungseoChoi23 Nov 9, 2025
de3f0a9
refactor: TenantAwareRepository JavaDoc ๋ณด์™„, see/throw ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€
YoungseoChoi23 Nov 9, 2025
cbdacf1
refactor: TenantAwareRepository JavaDoc ๋ณด์™„, see/throw ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€
YoungseoChoi23 Nov 9, 2025
53632f3
refactor: TenantAwareRepositoryImpl ๊ตฌํ˜„์ฒด JavaDoc ๊ฐœ์„ , throw ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€ ๋ฐ โ€ฆ
YoungseoChoi23 Nov 10, 2025
08e94db
refactor: TenantAwareInterceptor JavaDoc ๊ฐœ์„ , SQL ๋ณ€ํ™˜ ์˜ˆ์‹œ ์ฃผ์„ ์ถ”๊ฐ€, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฐœโ€ฆ
YoungseoChoi23 Nov 10, 2025
a73227a
fix: ๋ฆฌํŒฉํ† ๋ง ํŒŒ์ผ ์‚ญ์ œ
YoungseoChoi23 Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added [Help
Empty file.
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,22 @@
<tag>${project.version}</tag>
</configuration>
</plugin>

<!-- Maven Surefire Plugin for Testing -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.desktop/java.awt.font=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableJpaRepositories
@EnableAsync
@EnableScheduling
public class AgenticCpCoreApplication {
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/com/agenticcp/core/common/config/JpaConfig.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,52 @@
package com.agenticcp.core.common.config;

import com.agenticcp.core.common.interceptor.TenantAwareInterceptor;
import com.agenticcp.core.common.repository.TenantAwareRepositoryImpl;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

/**
* JPA ์„ค์ • ํด๋ž˜์Šค
* Hibernate Interceptor๋ฅผ ํ†ตํ•œ ํ…Œ๋„ŒํŠธ ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ ์„ค์ •
*
* @author AgenticCP Team
* @version 1.0.0
* @since 2025-01-01
*/
@Configuration
@EnableJpaAuditing
@EnableJpaRepositories(
basePackages = {"com.agenticcp.core.domain", "com.agenticcp.core.common.repository"},
repositoryBaseClass = TenantAwareRepositoryImpl.class
)
public class JpaConfig {

@Autowired
private TenantAwareInterceptor tenantAwareInterceptor;

/**
* Hibernate ์†์„ฑ ์ปค์Šคํ„ฐ๋งˆ์ด์ €
* StatementInspector๋ฅผ ํ†ตํ•ด SQL ์ฟผ๋ฆฌ ์ธํ„ฐ์…‰์…˜ ์„ค์ •
*
* @return HibernatePropertiesCustomizer
*/
@Bean
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer() {
return hibernateProperties -> {
// StatementInspector ์„ค์ • (Hibernate 5.4+)
hibernateProperties.put(AvailableSettings.STATEMENT_INSPECTOR, tenantAwareInterceptor);

// Interceptor ์„ค์ • (์ถ”๊ฐ€์ ์ธ ์—”ํ‹ฐํ‹ฐ ๋ ˆ๋ฒจ ์ฒ˜๋ฆฌ์šฉ)
hibernateProperties.put(AvailableSettings.INTERCEPTOR, tenantAwareInterceptor);

// SQL ๋กœ๊น… ํ™œ์„ฑํ™” (๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ํ…Œ๋„ŒํŠธ ํ•„ํ„ฐ๋ง ํ™•์ธ์šฉ)
hibernateProperties.put("hibernate.show_sql", false);
hibernateProperties.put("hibernate.format_sql", true);
};
}
}
91 changes: 38 additions & 53 deletions src/main/java/com/agenticcp/core/common/entity/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -1,86 +1,71 @@
package com.agenticcp.core.common.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
* ๊ธฐ๋ณธ ์—”ํ‹ฐํ‹ฐ - ํ…Œ๋„ŒํŠธ ์ •๋ณด ์—†์Œ
*
* <p>
* ์ „์—ญ ๊ธฐ๋Šฅ(ํ”Œ๋žซํผ ์„ค์ •, ํด๋ผ์šฐ๋“œ ์ œ๊ณต์ž ๋“ฑ)์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ ์ด์Šค ์—”ํ‹ฐํ‹ฐ์ž…๋‹ˆ๋‹ค.
* ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์˜ ๊ณตํ†ต ํ•„๋“œ(ID, ์ƒ์„ฑ/์ˆ˜์ • ์ •๋ณด, ์‚ญ์ œ ํ”Œ๋ž˜๊ทธ)๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* @author AgenticCP Team
* @version 1.0.0
* @since 2025-10-24
*/
@Getter
@Setter
@MappedSuperclass
@EntityListeners({
AuditingEntityListener.class,
com.agenticcp.core.common.audit.AuditEntityListener.class
})
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {

/**
* ์—”ํ‹ฐํ‹ฐ ๊ณ ์œ  ์‹๋ณ„์ž
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

/**
* ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ ์‹œ๊ฐ
* Spring Data JPA Auditing์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
*/
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;

/**
* ์—”ํ‹ฐํ‹ฐ ์ตœ์ข… ์ˆ˜์ • ์‹œ๊ฐ
* Spring Data JPA Auditing์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
*/
@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;

/**
* ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ์ž ์‹๋ณ„์ž (์‚ฌ์šฉ์ž๋ช… ๋˜๋Š” ์‹œ์Šคํ…œ ID)
*/
@Column(name = "created_by")
private String createdBy;

/**
* ์—”ํ‹ฐํ‹ฐ ์ตœ์ข… ์ˆ˜์ •์ž ์‹๋ณ„์ž (์‚ฌ์šฉ์ž๋ช… ๋˜๋Š” ์‹œ์Šคํ…œ ID)
*/
@Column(name = "updated_by")
private String updatedBy;

/**
* ๋…ผ๋ฆฌ ์‚ญ์ œ ํ”Œ๋ž˜๊ทธ
* true์ธ ๊ฒฝ์šฐ ์‚ญ์ œ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.
*/
@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;

// Getters and Setters
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}

public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}

public LocalDateTime getUpdatedAt() {
return updatedAt;
}

public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}

public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public String getUpdatedBy() {
return updatedBy;
}

public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}

public Boolean getIsDeleted() {
return isDeleted;
}

public void setIsDeleted(Boolean isDeleted) {
this.isDeleted = isDeleted;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.agenticcp.core.common.entity;

import com.agenticcp.core.domain.tenant.entity.Tenant;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
* ํ…Œ๋„ŒํŠธ ์ธ์‹ ์—”ํ‹ฐํ‹ฐ - ํ…Œ๋„ŒํŠธ ์ •๋ณด ํฌํ•จ
*
* <p>
* ํ…Œ๋„ŒํŠธ๋ณ„ ๊ฒฉ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ(์‚ฌ์šฉ์ž, ์กฐ์ง, ๋ฆฌ์†Œ์Šค ๋“ฑ)์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ ์ด์Šค ์—”ํ‹ฐํ‹ฐ์ž…๋‹ˆ๋‹ค.
* BaseEntity๋ฅผ ์ƒ์†๋ฐ›์•„ ๊ณตํ†ต ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ์ถ”๊ฐ€๋กœ ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* <p>
* TenantAwareEntityListener๋ฅผ ํ†ตํ•ด ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ ๊ธฐ๋ฐ˜์˜ ์ž๋™ ์„ค์ • ๋ฐ
* ๋ฉ€ํ‹ฐ ํ…Œ๋„Œ์‹œ ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* @author AgenticCP Team
* @version 1.0.0
* @since 2025-10-24
*/
@Getter
@Setter
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class, TenantAwareEntityListener.class})
public abstract class TenantAwareEntity extends BaseEntity {

/**
* ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์†ํ•œ ํ…Œ๋„ŒํŠธ
* ๋ฉ€ํ‹ฐ ํ…Œ๋„Œ์‹œ ํ™˜๊ฒฝ์—์„œ ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tenant_id", nullable = false)
private Tenant tenant;

/**
* ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํŠน์ • ํ…Œ๋„ŒํŠธ์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
*
* @param tenant ํ™•์ธํ•  ํ…Œ๋„ŒํŠธ ๊ฐ์ฒด
* @return ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ•ด๋‹น ํ…Œ๋„ŒํŠธ์— ์†ํ•˜๋ฉด true, ์•„๋‹ˆ๋ฉด false
*/
public boolean belongsToTenant(Tenant tenant) {
return this.tenant != null && this.tenant.equals(tenant);
}

/**
* ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํŠน์ • ํ…Œ๋„ŒํŠธ ID์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
*
* @param tenantId ํ™•์ธํ•  ํ…Œ๋„ŒํŠธ ID
* @return ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ•ด๋‹น ํ…Œ๋„ŒํŠธ ID์— ์†ํ•˜๋ฉด true, ์•„๋‹ˆ๋ฉด false
*/
public boolean belongsToTenant(Long tenantId) {
return this.tenant != null && this.tenant.getId().equals(tenantId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.agenticcp.core.common.entity;

import com.agenticcp.core.common.context.TenantContextHolder;
import com.agenticcp.core.common.enums.CommonErrorCode;
import com.agenticcp.core.common.exception.BusinessException;
import com.agenticcp.core.domain.tenant.entity.Tenant;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import lombok.extern.slf4j.Slf4j;

/**
* ํ…Œ๋„ŒํŠธ ์ธ์‹ ์—”ํ‹ฐํ‹ฐ ๋ฆฌ์Šค๋„ˆ
*
* <p>
* JPA ์—”ํ‹ฐํ‹ฐ ์ƒ๋ช…์ฃผ๊ธฐ ์ฝœ๋ฐฑ์„ ํ†ตํ•ด TenantAwareEntity๋ฅผ ์ƒ์†๋ฐ›์€ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•ด
* ์ž๋™์œผ๋กœ ํ˜„์žฌ ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* <p>
* ๋ฉ€ํ‹ฐ ํ…Œ๋„Œ์‹œ ํ™˜๊ฒฝ์—์„œ ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์—”ํ‹ฐํ‹ฐ ์ €์žฅ/์ˆ˜์ • ์‹œ
* ๋ฐ˜๋“œ์‹œ ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* @author AgenticCP Team
* @version 1.0.0
* @since 2025-10-24
*/
@Slf4j
public class TenantAwareEntityListener {

/**
* ์—”ํ‹ฐํ‹ฐ ์ €์žฅ ์ „์— ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
*
* <p>
* ์—”ํ‹ฐํ‹ฐ์— ํ…Œ๋„ŒํŠธ ์ •๋ณด๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ,
* TenantContextHolder์—์„œ ํ˜„์žฌ ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
* </p>
*
* @param entity ์ €์žฅํ•  ์—”ํ‹ฐํ‹ฐ (TenantAwareEntity๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด)
* @throws BusinessException ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
*/
@PrePersist
public void prePersist(Object entity) {
if (entity instanceof TenantAwareEntity tenantAwareEntity) {
setTenantIfNotSet(tenantAwareEntity, "prePersist");
}
}

/**
* ์—”ํ‹ฐํ‹ฐ ์ˆ˜์ • ์ „์— ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
*
* <p>
* ์—”ํ‹ฐํ‹ฐ์— ํ…Œ๋„ŒํŠธ ์ •๋ณด๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ,
* TenantContextHolder์—์„œ ํ˜„์žฌ ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
* (์ผ๋ฐ˜์ ์œผ๋กœ ์ˆ˜์ • ์‹œ์—๋Š” ์ด๋ฏธ ํ…Œ๋„ŒํŠธ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค)
* </p>
*
* @param entity ์ˆ˜์ •ํ•  ์—”ํ‹ฐํ‹ฐ (TenantAwareEntity๋ฅผ ์ƒ์†๋ฐ›์€ ๊ฐ์ฒด)
* @throws BusinessException ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
*/
@PreUpdate
public void preUpdate(Object entity) {
if (entity instanceof TenantAwareEntity tenantAwareEntity) {
setTenantIfNotSet(tenantAwareEntity, "preUpdate");
}
}

/**
* ์—”ํ‹ฐํ‹ฐ์— ํ…Œ๋„ŒํŠธ ์ •๋ณด๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ˜„์žฌ ์ปจํ…์ŠคํŠธ์˜ ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
*
* <p>
* ์ด๋ฏธ ํ…Œ๋„ŒํŠธ๊ฐ€ ์„ค์ •๋œ ๊ฒฝ์šฐ ๊ฑด๋„ˆ๋›ฐ๋ฉฐ, ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
* BusinessException์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
* </p>
*
* @param tenantAwareEntity ํ…Œ๋„ŒํŠธ ์ •๋ณด๋ฅผ ์„ค์ •ํ•  ์—”ํ‹ฐํ‹ฐ
* @param operation ์ˆ˜ํ–‰ ์ค‘์ธ ์ž‘์—… (prePersist ๋˜๋Š” preUpdate, ๋กœ๊น…์šฉ)
* @throws BusinessException ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ (TENANT_CONTEXT_NOT_SET)
*/
private void setTenantIfNotSet(TenantAwareEntity tenantAwareEntity, String operation) {
// ์ด๋ฏธ ํ…Œ๋„ŒํŠธ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด ๊ฑด๋„ˆ๋›ฐ๊ธฐ
if (tenantAwareEntity.getTenant() != null) {
log.debug("ํ…Œ๋„ŒํŠธ๊ฐ€ ์ด๋ฏธ ์„ค์ •๋จ: entity={}, operation={}",
tenantAwareEntity.getClass().getSimpleName(), operation);
return;
}

try {
// ํ˜„์žฌ ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ์—์„œ ํ…Œ๋„ŒํŠธ ์ •๋ณด ์กฐํšŒ
Tenant currentTenant = TenantContextHolder.getCurrentTenantOrThrow();

// ํ…Œ๋„ŒํŠธ ์ •๋ณด ์„ค์ •
tenantAwareEntity.setTenant(currentTenant);

log.debug("ํ…Œ๋„ŒํŠธ ์ž๋™ ์„ค์ • ์™„๋ฃŒ: tenantKey={}, entity={}, operation={}",
currentTenant.getTenantKey(),
tenantAwareEntity.getClass().getSimpleName(),
operation);

} catch (BusinessException e) {
// ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
log.error("ํ…Œ๋„ŒํŠธ ์„ค์ • ์‹คํŒจ: entity={}, operation={}, error={}",
tenantAwareEntity.getClass().getSimpleName(),
operation,
e.getMessage());

// ํ…Œ๋„ŒํŠธ ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์ˆ˜์ธ ๊ฒฝ์šฐ ์˜ˆ์™ธ ๋ฐœ์ƒ
throw new BusinessException(CommonErrorCode.TENANT_CONTEXT_NOT_SET,
"Tenant context is required for entity operations");
}
}
}
Loading