简体   繁体   中英

Why does Hibernate allow me to insert a null value on a foreign key constraint?

I am experimenting with jpa and hibernate relations. I'm using a table named users and a table named emails. A user can have many emails.

When I run my Spring boot application along with the following code I get one email record in my h2 database. The email_address of this record is testAddress and the user_username column of this record is null. The user_username column is listed as a foreign key on the emails table. My question is, why is emailRepository.save(email1) successful when there is no corresponding user in the database?

@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);
    }

}

Take a look at the documentation of the JoinColumn annotation: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumn.html#nullable()

It is mentioned:

If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply.

Since you did not specify a JoinColumn in your ManyToOne mapping, then Hibernate would assume the default JoinColumn . If you take a look at the JoinColumn.nullable attribute, it is defaulted to true. Thus, when Hibernate generates your schema, the foreign key column is by default NULLABLE.

You may need to explicitly add a @JoinColumn annotation on top of your @ManyToOne mapping and set its nullable attribute to false.

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

This way, it'll throw out an error when you try to insert email without a user.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM