为什么Hibernate可以让我在外键约束上插入无效的价值



我正在尝试JPA和Hibernate关系。我正在使用名为用户的表和名为电子邮件的表。用户可以有很多电子邮件。

当我运行Spring Boot应用程序以及以下代码时,我会在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);
    }
}

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

提到:

如果joincolumn注释本身是默认的,则单个连接列 假设并应用默认值。

由于您未在ManyToOne映射中指定JoinColumn,因此Hibernate会假定默认的JoinColumn。如果您查看JoinColumn.nullable属性,则将其默认为true。因此,当Hibernate生成您的架构时,默认情况下,外键列是无效的。

您可能需要在@ManyToOne映射的顶部明确添加@JoinColumn注释,然后将其nullable属性设置为false。

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

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

最新更新