Fix migration logical bug

pull/146/head
johnniang 2019-05-01 21:45:40 +08:00
parent f2b9fc768d
commit 4c8d38ae07
6 changed files with 126 additions and 39 deletions

View File

@ -3,9 +3,8 @@ package run.halo.app.model.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import run.halo.app.model.enums.CommentStatus;
import run.halo.app.utils.ServiceUtils;
import javax.persistence.*;
@ -102,7 +101,11 @@ public class BaseComment extends BaseEntity {
public void prePersist() {
super.prePersist();
if (parentId == null || parentId < 0) {
if (ServiceUtils.isEmptyId(id)) {
id = null;
}
if (ServiceUtils.isEmptyId(parentId)) {
parentId = 0L;
}

View File

@ -46,4 +46,5 @@ public interface BaseRepository<DOMAIN, ID> extends JpaRepository<DOMAIN, ID> {
* @return number of rows affected
*/
long deleteByIdIn(@NonNull Iterable<ID> ids);
}

View File

@ -10,6 +10,7 @@ import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.lang.Nullable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
@ -97,6 +98,7 @@ public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN,
* @return number of rows affected
*/
@Override
@Transactional
public long deleteByIdIn(Iterable<ID> ids) {
log.debug("Customized deleteByIdIn method was invoked");

View File

@ -13,6 +13,7 @@ import run.halo.app.model.vo.BaseCommentVO;
import run.halo.app.model.vo.BaseCommentWithParentVO;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@ -163,6 +164,15 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
@NonNull
Page<BaseCommentDTO> convertTo(@NonNull Page<COMMENT> commentPage);
/**
* Converts to base comment vo tree.
*
* @param comments comments list could be null
* @param comparator comment comparator could be null
* @return a comment vo tree
*/
List<BaseCommentVO> convertToVo(@Nullable List<COMMENT> comments, @Nullable Comparator<BaseCommentVO> comparator);
/**
* Target must exist.
*

View File

@ -219,9 +219,17 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// Set some default values
comment.setIpAddress(ServletUtils.getRequestIp());
comment.setUserAgent(ServletUtils.getHeaderIgnoreCase(HttpHeaders.USER_AGENT));
comment.setGavatarMd5(DigestUtils.md5Hex(comment.getEmail()));
if (comment.getIpAddress() == null) {
comment.setIpAddress(ServletUtils.getRequestIp());
}
if (comment.getUserAgent() == null) {
comment.setUserAgent(ServletUtils.getHeaderIgnoreCase(HttpHeaders.USER_AGENT));
}
if (comment.getGavatarMd5() == null) {
comment.setGavatarMd5(DigestUtils.md5Hex(comment.getEmail()));
}
if (authentication != null) {
// Comment of blogger
@ -368,15 +376,8 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
};
}
/**
* Converts to base comment vo tree.
*
* @param comments comments list could be null
* @param comparator comment comparator could be null
* @return a comment vo tree
*/
@NonNull
protected List<BaseCommentVO> convertToVo(@Nullable List<COMMENT> comments, @Nullable Comparator<BaseCommentVO> comparator) {
public List<BaseCommentVO> convertToVo(@Nullable List<COMMENT> comments, @Nullable Comparator<BaseCommentVO> comparator) {
if (CollectionUtils.isEmpty(comments)) {
return Collections.emptyList();
}
@ -408,32 +409,24 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
return;
}
List<COMMENT> children = new LinkedList<>();
// Get children
List<COMMENT> children = comments.stream()
.filter(comment -> Objects.equals(parentComment.getId(), comment.getParentId()))
.collect(Collectors.toList());
comments.forEach(comment -> {
if (parentComment.getId().equals(comment.getParentId())) {
// Stage the child comment
children.add(comment);
// Add children
children.forEach(comment -> {
// Convert to comment vo
BaseCommentVO commentVO = new BaseCommentVO().convertFrom(comment);
// Convert to comment vo
BaseCommentVO commentVO = new BaseCommentVO().convertFrom(comment);
// Add additional content
if (commentVO.getParentId() > 0) {
// TODO Provide an optional additional content
commentVO.setContent(String.format(COMMENT_TEMPLATE, parentComment.getId(), parentComment.getAuthor(), commentVO.getContent()));
}
// Init children container
if (parentComment.getChildren() == null) {
parentComment.setChildren(new LinkedList<>());
}
parentComment.getChildren().add(commentVO);
if (parentComment.getChildren() == null) {
parentComment.setChildren(new LinkedList<>());
}
parentComment.getChildren().add(commentVO);
});
// Remove all children
// Remove children
comments.removeAll(children);
if (!CollectionUtils.isEmpty(parentComment.getChildren())) {

View File

@ -7,6 +7,7 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import run.halo.app.exception.ServiceException;
@ -14,9 +15,12 @@ import run.halo.app.model.entity.*;
import run.halo.app.model.enums.AttachmentType;
import run.halo.app.model.enums.CommentStatus;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.repository.PostCommentRepository;
import run.halo.app.repository.SheetCommentRepository;
import run.halo.app.service.*;
import run.halo.app.utils.BeanUtils;
import run.halo.app.utils.JsonUtils;
import run.halo.app.utils.ServiceUtils;
import java.io.IOException;
import java.io.InputStreamReader;
@ -49,8 +53,12 @@ public class RecoveryServiceImpl implements RecoveryService {
private final PostCommentService postCommentService;
private final PostCommentRepository postCommentRepository;
private final SheetCommentService sheetCommentService;
private final SheetCommentRepository sheetCommentRepository;
private final SheetService sheetService;
private final PhotoService photoService;
@ -62,7 +70,9 @@ public class RecoveryServiceImpl implements RecoveryService {
CategoryService categoryService,
TagService tagService,
PostCommentService postCommentService,
PostCommentRepository postCommentRepository,
SheetCommentService sheetCommentService,
SheetCommentRepository sheetCommentRepository,
SheetService sheetService,
PhotoService photoService) {
this.attachmentService = attachmentService;
@ -72,7 +82,9 @@ public class RecoveryServiceImpl implements RecoveryService {
this.categoryService = categoryService;
this.tagService = tagService;
this.postCommentService = postCommentService;
this.postCommentRepository = postCommentRepository;
this.sheetCommentService = sheetCommentService;
this.sheetCommentRepository = sheetCommentRepository;
this.sheetService = sheetService;
this.photoService = photoService;
}
@ -203,7 +215,7 @@ public class RecoveryServiceImpl implements RecoveryService {
Post createdPost = postService.createOrUpdateBy(post);
Object commentsObject = postMap.get("comments");
// TODO Handle comments
// Handle comments
List<BaseComment> baseComments = handleComment(commentsObject, createdPost.getId());
List<PostComment> postComments = baseComments.stream()
@ -211,9 +223,11 @@ public class RecoveryServiceImpl implements RecoveryService {
.collect(Collectors.toList());
try {
// Build virtual comment
PostComment virtualPostComment = new PostComment();
virtualPostComment.setId(0L);
// Create comments
// TODO Don't use createInBatch method
List<PostComment> createdPostComments = postCommentService.createInBatch(postComments);
createPostCommentRecursively(virtualPostComment, postComments);
} catch (Exception e) {
log.warn("Failed to create post comments for post with id " + createdPost.getId(), e);
// Ignore this exception
@ -239,7 +253,11 @@ public class RecoveryServiceImpl implements RecoveryService {
// Create comments
try {
sheetCommentService.createInBatch(sheetComments);
// Build virtual comment
SheetComment virtualSheetComment = new SheetComment();
virtualSheetComment.setId(0L);
// Create comments
createSheetCommentRecursively(virtualSheetComment, sheetComments);
} catch (Exception e) {
log.warn("Failed to create sheet comments for sheet with id " + createdSheet.getId(), e);
// Ignore this exception
@ -248,6 +266,62 @@ public class RecoveryServiceImpl implements RecoveryService {
return createdSheet;
}
private void createPostCommentRecursively(@NonNull final PostComment parentComment, List<PostComment> postComments) {
Long oldParentId = parentComment.getId();
// Create parent
if (!ServiceUtils.isEmptyId(parentComment.getId())) {
PostComment createdComment = postCommentRepository.save(parentComment);
log.debug("Created post comment: [{}]", createdComment);
parentComment.setId(createdComment.getId());
}
if (CollectionUtils.isEmpty(postComments)) {
return;
}
// Get all children
List<PostComment> children = postComments.stream()
.filter(postComment -> Objects.equals(oldParentId, postComment.getParentId()))
.collect(Collectors.toList());
// Set parent id again
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
// Remove children
postComments.removeAll(children);
// Create children recursively
children.forEach(childComment -> createPostCommentRecursively(childComment, postComments));
}
private void createSheetCommentRecursively(@NonNull final SheetComment parentComment, List<SheetComment> sheetComments) {
Long oldParentId = parentComment.getId();
// Create parent
if (!ServiceUtils.isEmptyId(parentComment.getId())) {
SheetComment createComment = sheetCommentRepository.save(parentComment);
parentComment.setId(createComment.getId());
}
if (CollectionUtils.isEmpty(sheetComments)) {
return;
}
// Get all children
List<SheetComment> children = sheetComments.stream()
.filter(sheetComment -> Objects.equals(oldParentId, sheetComment.getParentId()))
.collect(Collectors.toList());
// Set parent id again
children.forEach(postComment -> postComment.setParentId(parentComment.getId()));
// Remove children
sheetComments.removeAll(children);
// Create children recursively
children.forEach(childComment -> createSheetCommentRecursively(childComment, sheetComments));
}
private List<BaseComment> handleComment(@Nullable Object commentsObject, @NonNull Integer postId) {
Assert.notNull(postId, "Post id must not be null");
@ -279,6 +353,10 @@ public class RecoveryServiceImpl implements RecoveryService {
baseComment.setPostId(postId);
baseComment.setParentId(getLongOrDefault(commentMap.getOrDefault("commentParent", "").toString(), 0L));
// Set create date
Long createTimestamp = getLongOrDefault(commentMap.getOrDefault("createDate", "").toString(), System.currentTimeMillis());
baseComment.setCreateTime(new Date(createTimestamp));
Integer commentStatus = getIntegerOrDefault(commentMap.getOrDefault("commentStatus", "").toString(), 1);
if (commentStatus == 0) {
baseComment.setStatus(CommentStatus.PUBLISHED);