uniqueConstraints

email에만 unique 설정

정답: uniqueConstraints는 복합키로도 unique 설정 가능

@Test
void insertAndUpdateTest() {
System.out.println("\n-- TEST#insertAndUpdateTest() ---------------------------------------------");
User user = new User();
user.setName("kname");
user.setEmail("kname@mail.com");
userRepository.save(user); // INSERT
user2=userRepository.findById(1L).orElseThrow(RuntimeException::new);
user2.setName("pname");
userRepository.save(user2); // UPDATE
System.out.println("\n------------------------------------------------------------\n");
}






@PrePersist
public void prePersist() {
System.out.println(">>> prePersist");
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
System.out.println(">>> preUpdate");
this.updatedAt = LocalDateTime.now();
}
@PreRemove
public void preRemove() {
System.out.println(">>> preRemove");
}
@PostPersist
public void postPersist() {
System.out.println(">>> postPersist");
}
@PostUpdate
public void postUpdate() {
System.out.println(">>> postUpdate");
}
@PostRemove
public void postRemove() {
System.out.println(">>> postRemove");
}
@PostLoad
public void postLoad() {
System.out.println(">>> postLoad");
}
public interface Auditable {
LocalDateTime getCreatedAt();
LocalDateTime getUpdatedAt();
void setCreatedAt(LocalDateTime createdAt);
void setUpdatedAt(LocalDateTime updatedAt);
}
@EntityListeners(value = {MyEntityListener.class})
public class User implements Auditable {
import com.lec.spring.domain.UserHistory;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserHistoryRepository extends
JpaRepository<UserHistory, Long> {
@Component
public class UserEntityListener {
@Autowired
private UserHistoryRepository userHistoryRepository;
@PreUpdate // User 가 UPDATE 수행하기 전
@PrePersist // User 가 INSERT 수행하기 전
public void addHistory(Object o) {
System.out.println(">>UserEntityListener addHistory() 호출");
User user = (User) o;
// UserHistory 에 UPDATE 될 User 정보 담아서 저장 (INSERT)
UserHistory userHistory = new UserHistory();
userHistory.setUserId(user.getId());
userHistory.setName(user.getName());
userHistory.setEmail(user.getEmail());
userHistoryRepository.save(userHistory); // INSERT
}
@EntityListeners(value = {MyEntityListener.class, UserEntityListener.class})
// Listener 안에서 스프링 빈 객체 수동으로 주입받기
UserHistoryRepository userHistoryRepository = BeanUtils.getBean(
UserHistoryRepository.class);
@EntityListeners(value = MyEntityListener.class)
@EnableJpaAuditing

@EntityListeners(value = AuditingEntityListener.class)
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
BaseEntity
@Data
@MappedSuperclass // (JPA)가 이 클래스의 속성을, 상속받는 Entity 에 포함시켜줌
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity{
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@EntityListeners(value = {UserEntityListener.class})
public class User extends BaseEntity implements Auditable {
Lombok의 toString 문제 해결
// 부모쪽도 toString으로 호출
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class User extends BaseEntity {
@Data
@MappedSuperclass // (JPA)가 이 클래스의 속성을, 상속받는 Entity 에 포함시켜줌
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity implements Auditable {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
@Service
public class BoardServiceImpl implements BoardService {
private final PostRepository postRepository;
public BoardServiceImpl(PostRepository postRepository) {
this.postRepository = postRepository;
}
@Override
public int write(Post post) {
postRepository.save(post);
return 1;
}
@Override
public Post detail(Long id) {
Optional<Post> postOptional = postRepository.findById(id);
if (postOptional.isPresent()) {
Post post = postOptional.get();
if (post.getViewCnt() == null) {
post.setViewCnt(1L);
} else {
post.setViewCnt(post.getViewCnt() + 1);
}
postRepository.save(post);
return post;
}
return null;
}
@Override
public List<Post> list() {
return postRepository.findAll(Sort.by(Sort.Order.desc("id")));
}
@Override
public Post selectById(Long id) {
return postRepository.findById(id).orElse(null);
}
@Override
public int update(Post post) {
// 주의! 위 post 매개변수에는 viewcnt 값이 없기 때문에
// 위 post 값으로 save 하면 viewcnt 값은 0 으로 초기화 된다.
Optional<Post> existingPost = postRepository.findById(post.getId());
if (existingPost.isPresent()) {
Post updatedPost = existingPost.get();
updatedPost.setSubject(post.getSubject());
updatedPost.setContent(post.getContent());
postRepository.save(updatedPost);
return 1;
}
return 0;
}
@Override
public int deleteById(Long id) {
if (postRepository.existsById(id)) {
postRepository.deleteById(id);
return 1;
}
return 0;
}
}
이런 식으로 사용된다.
refactoring 하면서 허무한 마음이 들었다. 내가 쓰던 sql query문들은 어디로..
물론 relation에 대해 배우면 좀 더 복잡해지겠지만, 일단 이걸로 돌아간다니!
ORM을 쓰는 이유가 너무나 뼈저리게 느껴졌다.

1:1
3편에서 이어서