2017-10-01 7 views
2

私はjpaと休止状態の関係を試しています。私はusersというテーブルとemailsというテーブルを使用しています。ユーザーは多数の電子メールを持つことができます。Hibernateはなぜ外部キー制約にNULL値を挿入できるのですか?

次のコードとともにSpringブートアプリケーションを実行すると、h2データベースに1つの電子メールレコードが取得されます。このレコードのemail_addressはtestAddressで、このレコードのuser_usernameカラムはnullです。 user_usernameカラムは、電子メールテーブルに外部キーとしてリストされます。私の質問は、なぜemailRepository.save(email1)は成功したのですか?

@Entity 
@Table(name = "emails") 
public class Email { 

    @Id 
    private String emailAddress; 

    @ManyToOne 
    private User user; 

    ... 

} 

@Entity 
@Table(name = "users") 
public class User { 

    @Id 
    private String username; 

    @OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true) 
    private Set<Email> emails; 

    ... 

} 

public interface UserRepository extends JpaRepository<User, String> { 

} 

public interface EmailRepository extends JpaRepository<Email, String> { 

} 

@Component 
public class UserRepositoryCommandLineRunner implements CommandLineRunner { 

    @Autowired 
    private EmailRepository emailRepository; 

    public void run(String... args) throws Exception { 
     Email email1 = new Email(); 
     email1.setEmailAddress("testAddress"); 
     emailRepository.save(email1); 
    } 

} 
+0

保存メソッドが完了したが、トランザクションのコミットが失敗したことを意味すると思いますか?または、新しい行が外部キーのためにnullでコミットされますか? –

+0

新しい行は、外部キーのためにnullでコミットされます。 – TheWebCoder

+0

http:// localhost:8080/h2-console/- > EMAILS - > Indexes - > FK ...のように、プロパティが一意でないと、USER_USERNAMEというFKとして表示されます。私はそれが私はusersテーブルに外部キーの関係があることを意味していると仮定しています。 – TheWebCoder

答えて

2

JoinColumn注釈のドキュメントを見てみましょう: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumn.html#nullable()

それは言及されています

JoinColumn注釈自体がデフォルト設定されている場合は、単一結合列 が想定され、デフォルト値が適用されます。

あなたManyToOneマッピングでJoinColumnを指定していないので、その後、HibernateはデフォルトJoinColumnを引き受けます。 JoinColumn.nullable属性を調べると、デフォルトでtrueに設定されます。したがって、Hibernateがスキーマを生成するとき、外部キー列はデフォルトでNULLABLEです。

@ManyToOneマッピングの上に@JoinColumn注釈を明示的に追加し、nullable属性をfalseに設定する必要があります。

@ManyToOne 
@JoinColumn(nullable=false) 
private User user; 

この方法では、ユーザーなしでメールを挿入しようとするとエラーが発生します。

+1

実際、 '@ManyToOne(optional = false)'を使うほうが意味があるかもしれません。これは、アプリケーションレベルで一貫性を維持し、db – crizzis

関連する問題