为啥 Hibernate 允许我在外键约束上插入空值?
Posted
技术标签:
【中文标题】为啥 Hibernate 允许我在外键约束上插入空值?【英文标题】:Why does Hibernate allow me to insert a null value on a foreign key constraint?为什么 Hibernate 允许我在外键约束上插入空值? 【发布时间】:2017-10-01 23:20:06 【问题描述】:我正在试验 jpa 和休眠关系。我正在使用一个名为 users 的表和一个名为 emails 的表。一个用户可以有许多电子邮件。
当我运行 Spring Boot 应用程序和以下代码时,我在我的 h2 数据库中获得了一条电子邮件记录。该记录的 email_address 为 testAddress,该记录的 user_username 列为空。 user_username 列在 emails 表中列为外键。我的问题是,为什么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);
【问题讨论】:
猜你的意思是保存方法完成但事务提交失败?或者新行提交正常,外键为空? 新行提交正常,外键为空。 当我转到localhost:8080/h2-console -> EMAILS -> 索引 ->FK... 时,它显示为一个名为 USER_USERNAME 的 FK,其属性非唯一。我假设这意味着我与 users 表有外键关系。 如果我将用户 id="testUser" 设置为 id="testAddress" 的电子邮件并保存该电子邮件,那么应用程序会抱怨找不到 testUser。所以这很好。我不确定是否可以向已经具有关系注释的内容添加非空约束。我不认为它应该让我添加一个空值吗? 【参考方案1】:看一下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;
这样,当您尝试在没有用户的情况下插入电子邮件时,它会抛出错误。
【讨论】:
实际上,使用@ManyToOne(optional=false)
可能更有意义。它将在应用程序级别强制执行一致性,甚至无需访问数据库以上是关于为啥 Hibernate 允许我在外键约束上插入空值?的主要内容,如果未能解决你的问题,请参考以下文章