質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

4930閲覧

Domaでのシステム制御項目を含むInsert文生成時における指定

sanezane

総合スコア91

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2019/03/16 10:50

編集2019/03/16 13:20

やりたいこと

ユーザ登録機能の作成。
###現状
ユーザ登録時に作成者(created_by)などのシステム制御項目を挿入するようにしたいが、Insert文のcreated_byのvalueにnullが入ってしまうためエラーで落ちる。
(ユーザ情報を格納するテーブルで「created_by(作成者)」をnot nullに指定しているため)
created_byへ値を設定している(ハズ)の箇所はDefaultEntityListenerというクラスです。ここで値が設定できていません。
以下にコードを示していますが、DefaultEntityListenerval createdBy = AuditInfoHolder.getAuditUser();の部分で値が取得できていないことがわかりました。
以下エラー画像(created_byは作成者)
イメージ説明

###テーブル定義

sql

1 2CREATE TABLE IF NOT EXISTS users( 3 user_id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ユーザID' 4 , name VARCHAR(100) DEFAULT NULL COMMENT '名前' 5 , email VARCHAR(100) DEFAULT NULL COMMENT 'メールアドレス' 6 , password VARCHAR(100) DEFAULT NULL COMMENT 'パスワード' 7 , created_by VARCHAR(50) NOT NULL COMMENT '登録者' 8 , created_at DATETIME NOT NULL COMMENT '登録日時' 9 , updated_by VARCHAR(50) DEFAULT NULL COMMENT '更新者' 10 , updated_at DATETIME DEFAULT NULL COMMENT '更新日時' 11 , deleted_by VARCHAR(50) DEFAULT NULL COMMENT '削除者' 12 , deleted_at DATETIME DEFAULT NULL COMMENT '削除日時' 13 , version INT(11) unsigned NOT NULL DEFAULT 1 COMMENT '改訂番号' 14 , PRIMARY KEY (user_id) 15 , KEY idx_users (email, deleted_at) 16) COMMENT='ユーザー'; 17

###ソース
作成者や作成日時などのシステム制御項目は共通化のためにUser.java(DTO)とは別でDomaDto.javaとして定義している。

User

1package com.example.demo.domain.dto; 2 3import com.example.demo.domain.dto.common.DomaDtoImpl; 4import lombok.Data; 5import org.seasar.doma.*; 6 7@Entity 8@Data 9@Table(name = "users") 10public class User extends DomaDtoImpl { 11 //自動採番設定 12 @Id 13 @Column(name = "user_id") 14 @GeneratedValue(strategy= GenerationType.IDENTITY) 15 Long id; 16 17 @Column 18 String name; 19 20 @Column 21 String email; 22 23 @Column 24 String password; 25 26} 27 28

DomaDto.javaではシステム制御項目を定義している。また、自動的に更新するようにDefaultEntityListener.javaを作成し指定している。

DomaDtoImpl

1package com.example.demo.domain.dto.common; 2 3import com.fasterxml.jackson.annotation.JsonIgnore; 4import lombok.Data; 5import org.seasar.doma.Column; 6import org.seasar.doma.Entity; 7import org.seasar.doma.Version; 8 9import java.io.Serializable; 10import java.time.LocalDateTime; 11 12@Entity(listener = DefaultEntityListener.class)// 自動的にシステム制御項目を更新するためにリスナーを指定する 13@Data 14public abstract class DomaDtoImpl implements DomaDto,Serializable { 15 16 // 作成者 17 @JsonIgnore 18 @Column 19 private String created_by; 20 21 //作成日時 22 @JsonIgnore 23 @Column 24 private LocalDateTime Created_at; 25 26 //更新者 27 @JsonIgnore 28 @Column 29 private String updated_by; 30 31 //更新日時 32 @JsonIgnore 33 @Column 34 private LocalDateTime updated_at; 35 36 //削除者 37 @JsonIgnore 38 @Column 39 private String deleted_by; 40 41 //削除日 42 @JsonIgnore 43 @Column 44 private LocalDateTime deleted_at; 45 46 // 楽観的排他制御で使用する改定番号 47 @Version 48 @Column(name = "version") 49 @JsonIgnore 50 Integer version; 51 52} 53 54

DefaultEntityListener

1 2package com.example.demo.domain.dto.common; 3 4import com.example.demo.common.utils.ReflectionUtils; 5import com.example.demo.domain.exception.DoubleSubmitErrorException; 6import lombok.NoArgsConstructor; 7import lombok.extern.slf4j.Slf4j; 8import lombok.val; 9import org.apache.commons.lang3.StringUtils; 10import org.seasar.doma.Id; 11import org.seasar.doma.jdbc.entity.EntityListener; 12import org.seasar.doma.jdbc.entity.PreDeleteContext; 13import org.seasar.doma.jdbc.entity.PreInsertContext; 14import org.seasar.doma.jdbc.entity.PreUpdateContext; 15 16 17import java.util.List; 18import java.util.Objects; 19 20import static java.util.stream.Collectors.toList; 21 22@NoArgsConstructor 23@Slf4j 24public class DefaultEntityListener<ENTITY> implements EntityListener<ENTITY> { 25 26 @Override 27 public void preInsert(ENTITY entity, PreInsertContext<ENTITY> context) { 28 // 二重送信防止チェック 29 val expected = DoubleSubmitCheckTokenHolder.getExpectedToken(); 30 val actual = DoubleSubmitCheckTokenHolder.getActualToken(); 31 32 if (expected != null && actual != null && !Objects.equals(expected, actual)) { 33 throw new DoubleSubmitErrorException(); 34 } 35 36 if (entity instanceof DomaDto) { 37 val domaDto = (DomaDto) entity; 38 val createdAt = AuditInfoHolder.getAuditDateTime(); 39 val createdBy = AuditInfoHolder.getAuditUser(); 40 41 domaDto.setCreated_at(createdAt); // 作成日 42 domaDto.setCreated_by(createdBy); // 作成者 43 } 44 } 45 46 @Override 47 public void preUpdate(ENTITY entity, PreUpdateContext<ENTITY> context) { 48 49 if (entity instanceof DomaDto) { 50 val domaDto = (DomaDto) entity; 51 val updatedAt = AuditInfoHolder.getAuditDateTime(); 52 val updatedBy = AuditInfoHolder.getAuditUser(); 53 54 val methodName = context.getMethod().getName(); 55 if (StringUtils.startsWith("delete", methodName)) { 56 domaDto.setDeleted_at(updatedAt); // 削除日 57 domaDto.setDeleted_by(updatedBy); // 削除者 58 } else { 59 domaDto.setUpdated_at(updatedAt); // 更新日 60 domaDto.setUpdated_by(updatedBy); // 更新者 61 } 62 } 63 } 64 65 @Override 66 public void preDelete(ENTITY entity, PreDeleteContext<ENTITY> context) { 67 68 if (entity instanceof DomaDto) { 69 val domaDto = (DomaDto) entity; 70 val deletedAt = AuditInfoHolder.getAuditDateTime(); 71 val deletedBy = AuditInfoHolder.getAuditUser(); 72 val name = domaDto.getClass().getName(); 73 val ids = getIds(domaDto); 74 75 // 物理削除した場合はログ出力する 76 log.info("データを物理削除しました。entity={}, id={}, deletedBy={}, deletedAt={}", name, ids, deletedBy, deletedAt); 77 } 78 } 79 80 /** 81 * Idアノテーションが付与されたフィールドの値のリストを返します。 82 * 83 * @param dto 84 * @return 85 */ 86 protected List<Object> getIds(DomaDto dto) { 87 return ReflectionUtils.findWithAnnotation(dto.getClass(), Id.class) 88 .map(f -> ReflectionUtils.getFieldValue(f, dto)).collect(toList()); 89 } 90 91} 92 93

created_byを自動更新させるためには他に何か指定が必要でしょうか。
またプロジェクト全体のソースコードはgithubへあげてあります。
ご指摘いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

システム制御項目をセットするaopの考慮が不足していました。
作成してgithubにアップしました。

投稿2019/03/16 17:26

sanezane

総合スコア91

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問