简体   繁体   中英

Cannot add or update a child row: a foreign key constraint fails - Bidirectional mapping in hibernate

Hi I have a problem with JPA...

DB:

数据库

Java classes (irrelevant fields are ommited):

User:

@Entity
public class User{
    @Id
    private int iduser;

    //bi-directional many-to-one association to UserInfo
    @OneToMany(mappedBy="user", cascade= {CascadeType.ALL}, fetch=FetchType.EAGER)
    private List<UserInfo> userInfos;
}

UserInfo:

@Entity
@Table(name="user_info")
public class UserInfo {
    @Id
    @Column(name="iduser_info")
    private int iduserInfo;

    //bi-directional many-to-one association to User
    @ManyToOne  
    private User user;
}

Currently when I try to do this (again I omitted setting irrelevant fields):

User u = new User();            
UserInfo info = new UserInfo();
u.addUserInfo(info);

em.persist(u); // save user

I get this error:

Cannot add or update a child row: a foreign key constraint fails (`webstore`.`user_info`, CONSTRAINT `fk_user_info_user` FOREIGN KEY (`user_iduser`) REFERENCES `user` (`iduser`) ON DELETE NO ACTION ON UPDATE NO ACTION)

I have been banging my head all day and I can't figure it out... I have also searched for solutions here but they all suggest that this error shows that I want to enter UserInfo without user_iduser value entered, but even if I add this before persist:

info.setUser(u);

it still doesn't work - is bidirectional mapping even supported with cascading? The desired effect is that User should be inserted and then all the UserInfos in the list after it refering the original User. How can I achieve that?

I don't want to do

SET foreign_key_checks = 0/1;

everytime =(

Try:

@ManyToOne
@JoinColumn(name="user_iduser", nullable=false)
private User user;

Then see if this works. I'm assuming that in user_info table, the user_id field is NOT NULL in your RDBMS. Also, since it's bidirectional, you will have to setXXX on UserInfo and User .

User u = new User();            
UserInfo info = new UserInfo();
info.setUser(u);
u.addUserInfo(info);

em.persist(u); // save user

Update: Are you sure you're specifying an ID for both User and UserInfo ? It looks like the ID is not set hence there is no reference to link UserInfo to User .

If the ID are AUTO_INCREMENT , then add the following after @Id annotation:

@GeneratedValue(strategy=GenerationType.IDENTITY)

this is worked for me in my example , i created books and library.

@Entity
@Table(name = "book")
public class Books{ 
        @Id
        private int library_id;
        private String libraryname;

        //add getters and setters bellow
}

@Entity
@Table(name = "library")
public class Book {
        @Id
        private int book_id;
        private String book_title;

        @JsonIgnore
        @ManyToOne
        @JoinColumn(name="library_id" , nullable = false)
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Library library;

       //set getters and setters
 }

in controller i used this method

@RequestMapping(value = "/{libraryId}/book", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public Book createBook(@PathVariable(value = "libraryId") Integer libraryId, @RequestBody Book book) {

        List<Book> books = new ArrayList<Book>();
        Library author1 = new Library();

        Optional<Library> byId = LibraryRepository.findById(libraryId);


        Library author = byId.get();

        book.setLibrary(author);

        Book book1 = bookRepository.save(book);
        books.add(book1);
        author1.setBooks((List<Book>) books);

        return book1;
}

我也有这个错误,通过在 iduser 顶部添加@GeneratedValue(strategy = GenerationType.IDENTITY)注释来修复此错误,并且您必须有外键 CASCADE ON DELETE、UPDATE。

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