Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package org.websoso.WSSServer.application;

import static org.websoso.WSSServer.exception.error.CustomUserNovelError.ALREADY_INTERESTED;
import static org.websoso.WSSServer.exception.error.CustomUserNovelError.NOT_INTERESTED;
import static org.websoso.WSSServer.exception.error.CustomUserNovelError.USER_NOVEL_ALREADY_EXISTS;

import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.websoso.WSSServer.user.domain.User;
Expand All @@ -32,21 +29,7 @@ public class LibraryInterestApplication {
public void registerAsInterest(User user, Long novelId) {
Novel novel = novelService.getNovelOrException(novelId);

UserNovel userNovel = user == null ? null : libraryService.getLibraryOrNull(user, novel);

if (userNovel != null && userNovel.getIsInterest()) {
throw new CustomUserNovelException(ALREADY_INTERESTED, "already registered as interested");
}

if (userNovel == null) {
try {
userNovel = createUserNovelByInterest(user, novel);
} catch (DataIntegrityViolationException e) {
userNovel = libraryService.getLibraryOrException(user, novelId);
}
}

userNovel.setIsInterest(true);
libraryService.registerInterest(user, novel);
}

/**
Expand All @@ -57,25 +40,13 @@ public void registerAsInterest(User user, Long novelId) {
*/
@Transactional
public void unregisterAsInterest(User user, Long novelId) {
UserNovel userNovel = libraryService.getLibraryOrException(user, novelId);
UserNovel library = libraryService.getLibraryOrNull(user, novelId);

if (!userNovel.getIsInterest()) {
throw new CustomUserNovelException(NOT_INTERESTED, "not registered as interest");
}

userNovel.setIsInterest(false);

if (userNovel.getStatus() == null) {
libraryService.delete(userNovel);
if (library == null) {
return;
}

libraryService.unregisterInterest(library);
}

private UserNovel createUserNovelByInterest(User user, Novel novel) {
if (libraryService.getLibraryOrNull(user, novel) != null) {
throw new CustomUserNovelException(USER_NOVEL_ALREADY_EXISTS, "this novel is already registered");
}

return libraryService.createLibrary(null, 0.0f, null, null, user, novel);
}
}
22 changes: 20 additions & 2 deletions src/main/java/org/websoso/WSSServer/library/domain/UserNovel.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
})
public class UserNovel extends BaseEntity {

public static final Float DEFAULT_RATING = 0.0f;
public static final ReadStatus DEFAULT_STATUS = null;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(nullable = false)
Expand Down Expand Up @@ -87,8 +90,23 @@ public static UserNovel create(ReadStatus status, Float userNovelRating, LocalDa
return new UserNovel(status, userNovelRating, startDate, endDate, user, novel);
}

public void setIsInterest(Boolean isInterest) {
this.isInterest = isInterest;
/**
* 관심 상태 지정
*/
public void markAsInterested() {
this.isInterest = true;
}

/**
* 관심 상태 해제
*/
public void unmarkAsInterested() {
this.isInterest = false;
}

public boolean isSafeToDelete() {
return !this.isInterest
&& this.status == null;
}

public void updateUserNovel(Float userNovelRating, ReadStatus status, LocalDate startDate, LocalDate endDate) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.websoso.WSSServer.library.repository;

import io.lettuce.core.dynamic.annotation.Param;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.websoso.WSSServer.novel.domain.Novel;
Expand All @@ -29,4 +31,28 @@ public interface UserNovelRepository extends JpaRepository<UserNovel, Long>, Use
List<UserNovel> findUserNovelByUser(User user);

Optional<UserNovel> findByNovel_NovelIdAndUser(Long novelId, User user);

@Modifying(clearAutomatically = true)
@Query(value = """
INSERT INTO user_novel (
user_id, novel_id, is_interest,
user_novel_rating, status,
created_date, modified_date
) VALUES (
:userId, :novelId, true,
:defaultRating,
:#{#defaultStatus?.name()},
NOW(), NOW()
)
ON DUPLICATE KEY UPDATE
is_interest = true,
modified_date = NOW()
""", nativeQuery = true)
void upsertInterest(
@Param("userId") Long userId,
@Param("novelId") Long novelId,
@Param("defaultRating") Float defaultRating,
@Param("defaultStatus") ReadStatus defaultStatus
);

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ public UserNovel getLibraryOrNull(User user, Novel novel) {
return userNovelRepository.findByNovel_NovelIdAndUser(novel.getNovelId(), user).orElse(null);
}

@Transactional(readOnly = true)
public UserNovel getLibraryOrNull(User user, long novelId) {
if (user == null) {
return null;
}

return userNovelRepository.findByNovel_NovelIdAndUser(novelId, user).orElse(null);
}

@Transactional
public UserNovel createLibrary(ReadStatus status, Float userNovelRating, LocalDate startDate, LocalDate endDate,
User user, Novel novel) {
Expand All @@ -56,6 +65,43 @@ public UserNovel createLibrary(ReadStatus status, Float userNovelRating, LocalDa
novel));
}

/**
* <p>관심있어요를 등록한다.</p>
* 서재 내역이 없다면, 서재 내역을 생성하면서 등록한다.
*
* @param user 사용자 Entity
* @param novel 서재 Entity
*/
@Transactional
public void registerInterest(User user, Novel novel) {
userNovelRepository.upsertInterest(
user.getUserId(),
novel.getNovelId(),
UserNovel.DEFAULT_RATING,
UserNovel.DEFAULT_STATUS
);
}

/**
* <p>관심있어요를 해제한다.</p>
* 만약, 서재 정보가 없다면 삭제한다.
*
* @param library 서재 Entity
*/
@Transactional
public void unregisterInterest(UserNovel library) {
if (Boolean.FALSE.equals(library.getIsInterest())) {
return;
}

library.unmarkAsInterested();

if (library.isSafeToDelete()) {
userNovelRepository.delete(library);
}
}

@Transactional
public void delete(UserNovel library) {
userNovelRepository.delete(library);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public List<Genre> getGenresOrException(List<String> names) {

List<String> uniqueNames = names.stream().distinct().toList();

List<Genre> genres = genreRepository.findByNameIn(uniqueNames);
List<Genre> genres = genreRepository.findByGenreNameIn(uniqueNames);

if (genres.size() != uniqueNames.size()) {
throw new CustomGenreException(GENRE_NOT_FOUND,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ public interface GenreRepository extends JpaRepository<Genre, Byte> {

Optional<Genre> findByGenreName(String name);

List<Genre> findByNameIn(List<String> names);
List<Genre> findByGenreNameIn(List<String> genreNames);
}