🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Java

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Spring Boot

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

Q&A

解決済

2回答

2598閲覧

@AutowiredでインジェクトしたUserServiceがnullになってしまう

shunji2740

総合スコア4

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Java

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Spring Boot

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

0グッド

0クリップ

投稿2021/01/29 02:46

編集2021/01/29 02:48

実現したいこと

現在Spring Bootを使用して予約サイトを作成しています。
今実現したいことは、自作のバリデーションを作成し、ユーザー登録を行う際にユーザーID・パスワードが既に登録されていないかをチェックし登録されていたらエラーメッセージを表示させたいです。

開発環境: Eclipse
Javaのバージョン: 11
Spring Bootのバージョン: 2.4.0

発生している問題・エラーメッセージ

ConstraintValidatorを実装したUserIdDuplicateCheckValidatorを作成しましたが、そこで@AutowiredしてインジェクトしたUserServiceインスタンスがnullになってしまいます。

java.lang.NullPointerException: null at mrs.app.user.UserIdDuplicateCheckValidator.isValid(UserIdDuplicateCheckValidator.java:30) ~[classes/:na] at mrs.app.user.UserIdDuplicateCheckValidator.isValid(UserIdDuplicateCheckValidator.java:1) ~[classes/:na] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:180) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:62) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:75) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:130) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:123) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:555) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:518) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:488) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:450) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:400) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:172) ~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final] at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:116) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:88) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:304) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:174) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:na] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final]

該当のソースコード

UserIdDuplicateCheck

1package mrs.app.user; 2 3import java.lang.annotation.Documented; 4import java.lang.annotation.ElementType; 5import java.lang.annotation.Retention; 6import java.lang.annotation.RetentionPolicy; 7import java.lang.annotation.Target; 8 9import javax.validation.Constraint; 10import javax.validation.Payload; 11 12@Documented 13@Constraint(validatedBy = { UserIdDuplicateCheckValidator.class }) 14@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) 15@Retention(RetentionPolicy.RUNTIME) 16public @interface UserIdDuplicateCheck { 17 18 String message() default "{mrs.app.reservation.UserIdDuplicateCheckValidator.message}"; 19 20 Class<?>[] groups() default {}; 21 Class<? extends Payload>[] payload() default {}; 22 23 24 @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, 25 ElementType.PARAMETER }) 26 @Retention(RetentionPolicy.RUNTIME) 27 @Documented 28 public @interface List { 29 UserIdDuplicateCheck[] value(); 30 } 31}

UserIdDuplicateCheckValidator

1package mrs.app.user; 2 3import javax.validation.ConstraintValidator; 4import javax.validation.ConstraintValidatorContext; 5 6import org.springframework.beans.factory.annotation.Autowired; 7 8import mrs.domain.model.User; 9import mrs.domain.service.user.UserService; 10 11 12public class UserIdDuplicateCheckValidator 13 implements ConstraintValidator<UserIdDuplicateCheck, User> { 14 15 private String message; 16 17 @Autowired 18 UserService userService; ★★ここが@Autowiredしてもnullになる★★ 19 20 @Override 21 public void initialize(UserIdDuplicateCheck constraintAnnotation) { 22 message = constraintAnnotation.message(); 23 } 24 25 @Override 26 public boolean isValid(User value, ConstraintValidatorContext context) { 27 String userId = value.getUserId(); 28 Boolean blResult = userService.checkDuplicate(userId); 29 30 if(!blResult) { 31 context.disableDefaultConstraintViolation(); 32 context.buildConstraintViolationWithTemplate(message).addPropertyNode("userId").addConstraintViolation(); 33 } 34 35 return true; 36 } 37} 38

UserService

1package mrs.domain.service.user; 2 3import org.springframework.beans.factory.annotation.Autowired; 4import org.springframework.dao.DataAccessException; 5import org.springframework.stereotype.Service; 6 7import mrs.domain.model.User; 8import mrs.domain.repository.user.EditUserRepositoryJdbc; 9import mrs.domain.repository.user.UserRepository; 10 11@Service 12public class UserService { 13 14 @Autowired 15 EditUserRepositoryJdbc userRepositoryJdbc; 16 17 @Autowired 18 UserRepository userRepository; 19 20 public void saveOrUpdate(User user, String userId) throws DataAccessException { 21 System.out.println("beforeFix: " + userId); 22 System.out.println("fixed: " + user.getUserId()); 23 24 userRepositoryJdbc.update(user, userId); 25 } 26 27 public boolean checkDuplicate(String userId) { 28 if (userRepository.countByUserId(userId) != 0) { 29 return false; 30 } 31 32 return true; 33 } 34} 35

UserRepository

1package mrs.domain.repository.user; 2 3import javax.persistence.LockModeType; 4 5import org.springframework.data.jpa.repository.JpaRepository; 6import org.springframework.data.jpa.repository.Lock; 7import org.springframework.stereotype.Repository; 8 9import mrs.domain.model.User; 10 11@Repository 12public interface UserRepository extends JpaRepository<User, String> { 13 14 @Lock(LockModeType.PESSIMISTIC_WRITE) 15 User findOneForUpdateByUserId(String userId); 16 long countByUserId(String userId); 17 18} 19

User

1package mrs.domain.model; 2 3import java.io.Serializable; 4 5import javax.persistence.Entity; 6import javax.persistence.Id; 7import javax.persistence.Table; 8import javax.validation.constraints.Email; 9import javax.validation.constraints.NotBlank; 10import javax.validation.constraints.Pattern; 11import javax.validation.constraints.Size; 12 13import org.hibernate.validator.constraints.Length; 14 15import mrs.app.user.UserIdDuplicateCheck; 16 17 18//会議室予約システムを利用するユーザー情報を格納するテーブル 19//Userエンティティー 20@Entity 21@Table(name = "usr") 22@UserIdDuplicateCheck(message="このユーザーIDは既に登録されています") 23public class User implements Serializable { 24 25 @Id 26 @NotBlank(groups=ValidGroup1.class) 27 @Email(groups=ValidGroup2.class) 28 private String userId; 29 30 @NotBlank(groups=ValidGroup1.class) 31 @Length(min=4, max=100, groups=ValidGroup2.class) 32 private String password; 33 34 @NotBlank(groups=ValidGroup1.class) 35 private String firstName; 36 37 @NotBlank(groups=ValidGroup1.class) 38 private String lastName; 39 40 /** 41 * 電話番号 42 */ 43 @NotBlank(groups=ValidGroup1.class) 44 @Pattern(regexp = "0\d{1,4}\d{1,4}\d{4}", groups=ValidGroup2.class) 45 private String phoneNumber; 46 47 @NotBlank(groups=ValidGroup1.class) 48 private String zipCode; 49 50 /** 51 * 住所 52 */ 53 @NotBlank(groups=ValidGroup1.class) 54 @Size(max = 200, groups=ValidGroup2.class) 55 private String address; 56 57 //@Enumerated(EnumType.STRING) 58 @NotBlank(groups=ValidGroup1.class) 59 private String roleName; 60 61 62 public String getUserId() { 63 return userId; 64 } 65 66 public void setUserId(String userId) { 67 this.userId = userId; 68 } 69 70 public String getPassword() { 71 return password; 72 } 73 74 public void setPassword(String password) { 75 this.password = password; 76 } 77 78 public String getFirstName() { 79 return firstName; 80 } 81 82 public void setFirstName(String firstName) { 83 this.firstName = firstName; 84 } 85 86 public String getLastName() { 87 return lastName; 88 } 89 90 public void setLastName(String lastName) { 91 this.lastName = lastName; 92 } 93 94 public String getRoleName() { 95 return roleName; 96 } 97 98 public void setRoleName(String roleName) { 99 this.roleName = roleName; 100 } 101 102 public String getPhoneNumber() { 103 return phoneNumber; 104 } 105 106 public void setPhoneNumber(String phoneNumber) { 107 this.phoneNumber = phoneNumber; 108 } 109 110 public String getZipCode() { 111 return zipCode; 112 } 113 114 public void setZipCode(String zipCode) { 115 this.zipCode = zipCode; 116 } 117 118 public String getAddress() { 119 return address; 120 } 121 122 public void setAddress(String address) { 123 this.address = address; 124 } 125 126} 127

試したこと

https://medium.com/@ssscripting/getting-autowired-fields-to-work-with-constraintvalidators-in-spring-boot-74424d5b0aaa

上記のサイトをもとにvalidationの設定を行いましたが、nullのままでした。
その後もひたすらググってみましたが、解決に至らずここで質問をさせて頂きます。
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

自己解決

以下のようにUserクラスにある自作バリデーションの第二引数に、ValidGroupクラスを持たせるとエラー無く正常に動作しました。正直なぜValidGroupクラスを指定しないとValidatorクラスで@Autowiredされないのか理解していません。Springの仕様を理解しきれていないので自分でも調べていきますが、ご存じの方はもしよければご教授お願いします。m(__)m

User

1//Userエンティティー 2@Entity 3@Table(name = "usr") 4@UserIdDuplicateCheck(message="このユーザーIDは既に登録されています", groups=ValidGroup2.class) 5public class User implements Serializable { 6

投稿2021/02/01 00:46

shunji2740

総合スコア4

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

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

0

Spring のコンテナに UserIdDuplicateCheckValidator が登録されたないから、
Injection してくれてないとかってないですかね?

UserIdDuplicateCheckValidator class に @Component アノテーションつけたら動いたりしませんでしょうか?

投稿2021/01/29 12:44

kiino

総合スコア557

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

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

shunji2740

2021/01/30 03:59

返信ありがとうございます。 何らかの理由で、UserIdDuplicateCheckValidatorがコンテナに登録されていないのだと思います。 UserIdDuplicateCheckValidatorクラスに@Componentをつけてみましたが駄目でした..。 ほかの自作のバリデーションクラスでは、問題なくUserServiceが@Autowired出来ていたので問題はUserIdDuplicateCheckValidatorクラスにあるのだと思いますがまだ解決できていません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問