【ポートフォリオ開発記】 #3 ユーザーエンティティの作成

## 今回書いたコード

今回はusersテーブルのエンティティを作成してみました。
まだ動作確認をしていないのでそのままコピペしても動く保証はありません。

エラー解決に関してもまとめたいので、
何かエラーが起きた時はそれに関しても記事を書いてみようと思います。

```java
package com.example.noteapp.backend.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;

@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true, length = 50)
    private String username;

    @Column(nullable = false, unique = true, length = 100)
    private String email;

    @Column(nullable = false, length = 255)
    private String password;

    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserStatus status = UserStatus.ACTIVE;

    public static enum UserStatus {
        ACTIVE,
        INACTIVE,
        BANNED
    }
}
```



## 使用しているアノテーション

| アノテーション               | 意味 |
|----------------------------|------|
| `@Entity`                 | このクラスが **JPAエンティティ（= DBのテーブルと対応する）** であることを示します。<br>→ JPAがこのクラスをDBに保存・取得できるようになります。 |
| `@Table(name = "users")`  | 対応するDBテーブルの名前を指定します。<br>→ デフォルトではクラス名（User）と同じ名前のテーブルが使われますが、ここでは明示的に `users` テーブルと指定しています。 |
| `@Data`（Lombok）          | 以下を自動生成してくれます：<br>- getter / setter<br>- equals / hashCode<br>- toString<br>- 全フィールドのアクセサ |
| `@NoArgsConstructor`（Lombok） | 引数なしのコンストラクタを自動生成します（JPAで必要）。 |
| `@AllArgsConstructor`（Lombok） | すべてのフィールドを引数に取るコンストラクタを自動生成します。 |

:::note info
JPA（Java Persistence API） は、
Javaアプリケーションとデータベースの橋渡しをしてくれる仕組みです。

「Javaのクラスを、SQLを書かずにそのままデータベースのテーブルとつなげてくれる機能」です。

:::

## 不明点

生成AIに解説を求めたりしていろいろ教えてもらったのですが、理解できないところがあったので記録しておこうと思います。今回はやり切ることが最大の目標なので、不明点は書き残して後から解決していこうと思います。



- @NoArgsConstructor
どうやらこれがないと動かないらしいということは理解しましたが、詳しい仕様についてはあまり理解できませんでした。コンストラクタの理解があまりできていない自覚があるのでそこが原因かもしれません。もっと勉強しなければ…

>内部的にリフレクションを使って new User() のようにインスタンスを自動生成します。
このとき 引数なしのコンストラクタがないと動きません。
つまり、JPAを使うときは絶対に必要です。

ということらしいです。

---
- @AllArgsConstructorについて

>全フィールドを一気に初期化できる。

と解説があったのですが、これの利点があまりわかりませんでした。

① @AllArgsConstructor を使わない場合
```java
User user = new User();
user.setId(1L);
user.setUsername("taro");
user.setEmail("taro@example.com");
user.setPassword("pass123");
user.setCreatedAt(LocalDateTime.now());
user.setUpdatedAt(LocalDateTime.now());
user.setStatus(User.UserStatus.ACTIVE);
```
② @AllArgsConstructor を使った場合
```java
User user = new User(
    1L,
    "taro",
    "taro@example.com",
    "pass123",
    LocalDateTime.now(),
    LocalDateTime.now(),
    User.UserStatus.ACTIVE
);
```
今の所の理解としてはスッキリ書けていいね！ってくらいです。



## まとめ

理解できていないところもありますが、実際に手を動かして体験することで理解できることもあると思うので、このまま進めていこうと思います！
現状まだ自分で考えてコードを書くことができていないので、ユーザー機能が終わったら別テーブルで同じことをやってみようと思います！