LoginSignup
35
32

More than 5 years have passed since last update.

JPAでEntityを親クラスと子クラスに分ける方法

Posted at

システムによって全テーブルに共通したカラムが存在することがあると思います。
(楽観ロック用のバージョニングカラムや登録日、更新日、登録者名、更新者名など)

JPAのEntityクラスを作成するときに全Entityに同じ変数を作るのはイヤだったので、上位クラスを作ってまとめられないかな、と思って調べてみたらその方法がありました。

上位クラスに@Entityではなく@MappedSuperclassアノテーションをつけるだけです。
これだけで、上位クラスを継承したEntityクラスで共通カラムを使用することができました。

AbstractEntity.java
package jp.co.test.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * DB共通Entity
 */
@MappedSuperclass
public class AbstractEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 登録日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "TOROKU_DATE")
    private Date torokuDate;

    /** 更新日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "KOSIN_DATE")
    private Date kosinDate;

    /** バージョン */
    @Version
    @Column(name = "VERSION")
    private Integer version;

    // getter,setter
NameT.java
package jp.co.test.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "NAMET")
public class NameT extends AbstractEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    private Integer id;

    @Column(name = "NAME")
    private String name;

    // getter,setter

さらに、@PrePersist@PreUpdateと併用して、登録日、更新日を自動で設定することも可能

AbstractEntity.java
package jp.co.test.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * DB共通Entity
 */
@MappedSuperclass
public class AbstractEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 登録日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "TOROKU_DATE")
    private Date torokuDate;

    /** 更新日 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "KOSIN_DATE")
    private Date kosinDate;

    /** バージョン */
    @Version
    @Column(name = "VERSION")
    private Integer version;

    /**
     * 登録前処理
     */
    @PrePersist
    public void prePersist() {
        // 登録日、更新日を設定
        Date date = new Date();
        torokuDate = date;
        kosinDate = date;
    }

    /**
     * 更新前処理
     */
    @PreUpdate
    public void preUpdate() {
        // 更新日を設定
        kosinDate = new Date();
    }

    // getter,setter

insertやupdateするたびに手動で日付設定する必要もなくなるし、上位クラスで処理を一つにまとめることもできました。
※昔やってたプロジェクトでは手動で設定してたので誰もJPA知らなかったんだなって思いました。。。

image

参考リンク

35
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
32