JPA

  • DBアクセスの標準仕様

FetchType

関連カラムの読み込みのタイミングを決める

  • FetchType.EAGER: entity取得時に読み込み.
    • @OneToOne, @ManyToOne ではデフォルト
  • FecthType.LAZY: 関連フィールドにアクセスした時に(getter内で)読み込み.
    • @ManyToMany, @OneToMany ではデフォルト
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
var tweets: List<Tweets>? = null,

JPA Foreign Key

@Entity
@Table(name = "users")
data class ParentEntity(
  @Id
  @Column(name = "id")
  var id: UUID? = null,
 
	@OneToMany(mappedBy = "user_id", cascade = [CascadeType.ALL])
  var children: List<Child>? = null
)
create table products (
  id uuid primary key not null,
  user_id uuid not null
);
 
alter table products add constraint fk_product_user_id
	foreign key (user_id)
	references users (id);

は以下に対応

@Entity
@Table(name = "products")
data class ProductEntity(
  @Id
  @Column(name = "id")
  var id: UUID? = null,
 
	@ManyToOne
  @JoinColumn(name = "user_id", referencedColumnName = "user_id")
  var user: UserEntity? = null
)

カスケーディング

  • CascadeType.ALL: を @OneToMany 等につけると, エンティティ削除時にその参照先も削除される

Entity

lifecycle

                    ○      ◎
                new |      ^ GC
                    v      |
                   +---------+
                   |   NEW   | <--------------+
                   +---------+                |
   find/JPQL             |                    |
○----------------------+ |                    |
                       | | persist            |
                       v v                    |
+---------+  merge   +---------+  remove   +---------+
|         | -------> |         | --------> |         |
|DETACHED | <------- | MANAGED |           | REMOVED |
|         |  clear   |         | <-+       |         |
+---------+  detach  +---------+   |       +---------+
                       ^    |      |
                       |    +------+
                       |      refresh
                       |      setter
                       v
                    +-------------+
                    +-------------+
                    |   Database  |
                    +-------------+

mapping

  • String 型は varchar(255) にマッピングされるのか, @Column.length のデフォルト値は255.
  • (お気持ち): レビュー時知ってたら弾いてくれ

@Transactional

2022-07-25

デバッグ

2022-04-18

logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace

application.yaml に書くとSQLとバインドされたパラメータがわかる

SpringでSQLのパラメータログに出す

  • application.yaml
logging:
  path: "logs/"
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql: TRACE
  • 期間とかパラメータ取れるようになったのでそれを考慮したテストを書く

Pagination

2022-07-21
ところで, JPA Paginationについても詳しくないな

public interface UserRepository extends JpaRepository<User, Long> {
    @Query(value="SELECT * FROM USERS WHERE LASTNAME = ?1", nativeQuery=true)
    Page<User> findByLastname(String lastname, Pageable pageable);
}

save(), saveFlush()

参考文献