为什么Hibernate允许我在外键约束上插入空值?

时间:2017-10-01 23:20:06

标签: java spring hibernate jpa h2

我正在尝试jpa和hibernate关系。我正在使用名为users的表和名为emails的表。用户可以拥有许多电子邮件。

当我运行Spring启动应用程序以及以下代码时,我在h2数据库中收到一封电子邮件记录。此记录的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);
    }

}

1 个答案:

答案 0 :(得分:2)

看一下JoinColumn注释的文档: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumn.html#nullable()

提到:

  

如果JoinColumn注释本身是默认的,则为单个连接列   假定并且默认值适用。

由于您未在JoinColumn映射中指定ManyToOne,因此Hibernate将采用默认JoinColumn。如果您查看JoinColumn.nullable属性,则默认为true。因此,当Hibernate生成您的模式时,外键列默认为NULLABLE。

您可能需要在@JoinColumn映射之上明确添加@ManyToOne注释,并将其nullable属性设置为false。

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

这样,当您尝试在没有用户的情况下插入电子邮件时,它会抛出错误。