无法添加或更新子行:外键约束失败 - 在hibernate中进行双向映射

时间:2015-04-08 15:03:45

标签: java hibernate java-ee jpa

嗨我有JPA问题......

DB:

Database

Java类(无关字段被忽略):

用户:

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

目前,当我尝试这样做时(我再次省略了设置不相关的字段):

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

em.persist(u); // save user

我收到此错误:

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)

我整天都在敲我的脑袋,我无法弄明白......我也在这里寻找解决方案,但他们都建议这个错误表明我想输入UserInfo而没有输入user_iduser值,但是如果我在坚持之前添加它:

info.setUser(u);

它仍然无效 - 双向映射甚至支持级联?期望的效果是,在引用原始用户之后,应该插入用户,然后插入列表中的所有UserInfos。我怎样才能做到这一点?

我不想做

SET foreign_key_checks = 0/1;

每次=(

2 个答案:

答案 0 :(得分:4)

尝试:

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

然后看看这是否有效。我假设在user_info表中,您的RDBMS中user_id字段为NOT NULL。此外,由于它是双向的,您必须setXXXUserInfoUser

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

em.persist(u); // save user

更新:您确定要为UserUserInfo指定ID吗?看起来ID未设置,因此没有引用UserInfoUser的链接。

如果ID为AUTO_INCREMENT,请在@Id注释后添加以下内容:

@GeneratedValue(strategy=GenerationType.IDENTITY)

答案 1 :(得分:0)

在我的示例中,这对我有用, 我创建了书籍和图书馆。

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

在控制器中,我使用了这种方法

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