diff --git a/src/main/java/com/example/gp_backend_data/graph/domain/entity/Graph.java b/src/main/java/com/example/gp_backend_data/graph/domain/entity/Graph.java index 053b0e5..8291106 100644 --- a/src/main/java/com/example/gp_backend_data/graph/domain/entity/Graph.java +++ b/src/main/java/com/example/gp_backend_data/graph/domain/entity/Graph.java @@ -12,7 +12,9 @@ @NoArgsConstructor @AllArgsConstructor @Builder -@Table(name = "Graph", schema = "gp_data") +@Table(name = "Graph", schema = "gp_data", uniqueConstraints = { + @UniqueConstraint(columnNames = "space_id") +}) public class Graph { @Id diff --git a/src/main/java/com/example/gp_backend_data/graph/service/GraphService.java b/src/main/java/com/example/gp_backend_data/graph/service/GraphService.java index 919e8bc..1009dff 100644 --- a/src/main/java/com/example/gp_backend_data/graph/service/GraphService.java +++ b/src/main/java/com/example/gp_backend_data/graph/service/GraphService.java @@ -7,6 +7,7 @@ import com.example.gp_backend_data.utils.UUIDHelper; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,22 +23,42 @@ public class GraphService { private final UUIDHelper uuidHelper; //특정 스페이스의 그래프 조회 + @Transactional public GraphResponse getGraphBySpaceId(UUID spaceId) { - Optional graphOptional = graphRepository.findBySpaceId(uuidHelper.convertUUIDToByteArray(spaceId)); + byte[] spaceIdBytes = uuidHelper.convertUUIDToByteArray(spaceId); - return graphOptional.map(graph -> { - try { - return new GraphResponse( - uuidHelper.convertByteArrayToUUID(graph.getGraphId()), - uuidHelper.convertByteArrayToUUID(graph.getSpaceId()), - objectMapper.readTree(graph.getData()) - ); - } catch (Exception e) { - throw new RuntimeException("Error parsing graph data", e); - } - }).orElseThrow(() -> new IllegalArgumentException("Graph not found for spaceId: " + spaceId)); + Graph graph = graphRepository.findBySpaceId(spaceIdBytes) + .orElseGet(() -> createNewGraphForSpace(spaceIdBytes)); + + try { + return new GraphResponse( + uuidHelper.convertByteArrayToUUID(graph.getGraphId()), + uuidHelper.convertByteArrayToUUID(graph.getSpaceId()), + objectMapper.readTree(graph.getData()) + ); + } catch (Exception e) { + throw new RuntimeException("Error parsing graph data", e); + } } + private Graph createNewGraphForSpace(byte[] spaceIdBytes) { + try { + UUID newGraphId = UUID.randomUUID(); + + Graph graph = new Graph(); + graph.setGraphId(uuidHelper.convertUUIDToByteArray(newGraphId)); + graph.setSpaceId(spaceIdBytes); + graph.setData("{}"); // 또는 AI summary 생성 로직 + + return graphRepository.save(graph); + } catch (DataIntegrityViolationException e) { + // 동시성 문제로 인한 중복 생성 방지 + return graphRepository.findBySpaceId(spaceIdBytes) + .orElseThrow(() -> new IllegalStateException("Graph creation failed due to race condition")); + } + } + + //그래프 세부 정보 조회 public GraphResponse getGraphById(UUID graphId) { Optional graphOptional = graphRepository.findByGraphId(uuidHelper.convertUUIDToByteArray(graphId));