[업무 일지] 10/13) 기존의 테이블을 jpa로 변경하기(3) - one to one, many to one

zooju·2022년 10월 13일
0
post-custom-banner

jpa(3) → 여러가지 fk 옮기기

날짜: 2022년 10월 13일

10/13

  • user와 one to one 관계에 있는 social 테이블 Jpa로 옮기고 테스트코드로 확인하기
  • user와 one to many 관계에 있는 wallet 관련 테이블들 jpa로 옮기고 테스트코드로 확인하기

1. social 테이블 (user와 one to one)

1) 특이점

social의 pk = user와 이어주는 fk

2) 🚨 Entity, Repository → 문제 해결

원래 다음과 같이 코드를 작성했었다.

@Entity
@Getter
@Setter
public class social {
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "userId")
    private user userId;

    private String twitter;
    private String facebook;
    private String discord;
    private String link;
}
public interface SocialRepository extends JpaRepository<social, user>{

}

이렇게 작성하니 composite key는 serializable해야한다는 오류가 나왔다.

내 pk는 복합키가 아닌데 복합키 오류가 나는 것을 보고

Id와 fk가 겹치면 class로 받는게 아니라 뭔가 다르게 해야한다고 생각했다.

그리고 다음 방법으로 해결했다.

@Entity
@Getter
@Setter
public class social {
    @Id
    private String userId;

    @OneToOne
    @PrimaryKeyJoinColumn
    private user user;

    private String twitter;
    private String facebook;
    private String discord;
    private String link;
}
public interface SocialRepository extends JpaRepository<social, String>{
}

여기서 중요한건 PrimaryKeyJoinColumn!

  • JoinColumn
외래 미 매핑할 때 사용
  • PrimaryKeyJoinColumn

primarykeyjoincolumn은 primary 키가 fk일 때 사용할 수 있다.
  • 참고

Java Persistence/Identity and Sequencing - Wikibooks, open books for an open world

PrimaryKeyJoinColumn (hibernate-jpa-2.1-api 1.0.0.Final API)

3) Test code

@RunWith(SpringRunner.class)
@SpringBootTest
public class SocialRepositoryTest {
    @Autowired
    private SocialRepository socialRepository;

    @Test
    @Transactional
    public void read() {
        List<social> socialList = socialRepository.findAll();
        System.out.println(socialList);
        Optional<social> social = socialRepository.findById("gkrry2723");

        social.ifPresent(selectedWT -> {
            System.out.println(social);
        });
    }
}

2. Wallet 관련 table (many to one)

1) walletType

@Entity
@Getter @Setter
public class walletType {
    @Id
    private String name;

    private String icon;
    private Integer index;

    @OneToMany(mappedBy = "walletType")
    private List<wallet> wallets = new ArrayList<>();
}
public interface WalletRepository extends JpaRepository<wallet, String> {
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class WalletTest {
    @Autowired
    private WalletRepository walletRepository;

    @Test
    @Transactional
    public void testWallet(){
        wallet wallet = new wallet();
        walletType walletType = new walletType();

        walletType.setName("Metamask");
        wallet.setAddress("testWallet");
        wallet.setWalletType(walletType);

        wallet savedWallet = walletRepository.save(wallet);
        Optional<wallet> findWallet = walletRepository.findById("testWallet");

        Assertions.assertThat(findWallet.get().getAddress()).isEqualTo(savedWallet.getAddress());
        Assertions.assertThat(savedWallet).isEqualTo(findWallet.get());
    }
}

2) wallet

@Entity
@Getter
@Setter
public class wallet {
    @Id
    private String address;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "walletType")
    private walletType walletType;

    @OneToMany(mappedBy = "wallet")
    private List<userWallet> userWallets = new ArrayList<>();

}
public interface WalletRepository extends JpaRepository<wallet, String> {
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class WalletTest {
    @Autowired
    private WalletRepository walletRepository;

    @Test
    @Transactional
    public void testWallet(){
        wallet wallet = new wallet();
        walletType walletType = new walletType();

        walletType.setName("Metamask");
        wallet.setAddress("testWallet");
        wallet.setWalletType(walletType);

        wallet savedWallet = walletRepository.save(wallet);
        Optional<wallet> findWallet = walletRepository.findById("testWallet");

        Assertions.assertThat(findWallet.get().getAddress()).isEqualTo(savedWallet.getAddress());
        Assertions.assertThat(savedWallet).isEqualTo(findWallet.get());

    }
}

3) userWallet

@Entity
@Getter
@Setter
@DynamicInsert
@DynamicUpdate
public class userWallet {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer index;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user")
    private user user;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="walletAddress")
    private wallet wallet;

    @ColumnDefault("default")
    private String chain;

    @Column(updatable = false, nullable = false)
    @CreationTimestamp
    private Timestamp createdAt;
}
public interface UserWalletRepository extends JpaRepository<userWallet, Integer> {
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserWalletTest {
    @Autowired
    private UserWalletRepository userWalletRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private WalletRepository walletRepository;

    @Test
    @Transactional
    public void testUserWallet(){
        userWallet userWallet = new userWallet();

        Optional<wallet> wallet = walletRepository.findById("0xf9F3Ea76C7Be559B4D4C9B3Ee2c3E05484A84420");
        user user = userRepository.find("gkrry2723");
        userWallet.setWallet(wallet.get());
        userWallet.setUser(user);

        userWallet savedUserWallet = userWalletRepository.save(userWallet);
    }
}
  • default를 쓰는 table은 @DynamicInsert, @DynamicUpdate 를 꼭 추가해줘야 default값이 들어가 작동하게 된다.

오늘 여러가지 해보면서 table을 jpa로 옮기는 것에 감을 잡은 것 같다. erd cloud에 db 스키마 옮기면서 다음주까지 완성 할 수 있을 것 같다.

jpa 다 옮기면 repository에 대해 좀 더 깊이 공부해봐야겠다.

profile
이것 저것 새로운 분야에 관심이 많은 서버 개발자
post-custom-banner

0개의 댓글