首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Hibernate一对多关系java.sql.SQLIntegrityConstraintViolationException:列'person_id‘不能为空。

Hibernate一对多关系java.sql.SQLIntegrityConstraintViolationException:列'person_id‘不能为空。
EN

Stack Overflow用户
提问于 2018-11-23 15:48:31
回答 5查看 1.6K关注 0票数 1

我是新来的hibernate,学习doc保存持久对象

遵循冬眠病,这是人与电话的一对多关系。

代码语言:javascript
运行
复制
@Entity
@Table(name = "phone")
public class Phone {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "number")
    private String number;

    @ManyToOne(fetch = FetchType.LAZY)
    private Person person;

  //omit setter and getter
}

@Entity
@Table(name = "person")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String username;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
    private List<Phone> phones = new ArrayList<>();
   //omit getter and setter 
}

我是一个执着的人,加上一部手机,错误被抛出

代码语言:javascript
运行
复制
@Test
public void say() {
    Person person = new Person();
    person.setUsername("aaaa");

    Phone phone = new Phone();
    phone.setNumber("111");

    person.getPhones().add(phone);

    personService.save(person);
}

这是Dao持久化

代码语言:javascript
运行
复制
public class PersonDaoImpl implements PersonDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void save(Person person) {
        entityManager.persist(person);
}

更新服务代码,服务只需保存人员

代码语言:javascript
运行
复制
@Service(value = "personService")
public class PersonServiceImpl implements PersonService {
    @Autowired
    private PersonDao personDao;

    @Transactional
    @Override
    public void save(Person person) {
        personDao.save(person);
    }
}

错误信息:

代码语言:javascript
运行
复制
    23:35:47.059 [main] DEBUG org.hibernate.engine.spi.ActionQueue - Executing identity-insert immediately
23:35:47.062 [main] DEBUG org.hibernate.SQL - 
    insert 
    into
        phone
        (number, person_id) 
    values
        (?, ?)
23:35:47.297 [main] DEBUG org.hibernate.engine.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
java.sql.SQLIntegrityConstraintViolationException: Column 'person_id' cannot be null

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-11-23 16:21:58

添加@GeneratedValue注释,以指定两个实体的主键将在代码之外填充。

代码语言:javascript
运行
复制
@Entity
@Table(name = "phone")
public class Phone {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

    @Column(name = "number")
    private String number;

    @JoinColumn("person_id")
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Person person;

  //omit setter and getter
}


public class Person {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;
    private String username;

    @OneToMany(mappedBy = "person")
    private List<Phone> phones = new ArrayList<>();
   //omit getter and setter 
}

此外,您需要持久化Person对象而不是Phone对象,因为没有从Phone配置到Person的级联。如果无法做到这一点,请将CascadeType on Person切换到none,并将级联设置在Phone上,如上面所示。

您还应该在@JoinColumn实体上添加一个Phone注释,这样hibernate就知道了外键列。

票数 2
EN

Stack Overflow用户

发布于 2018-11-23 16:42:47

你漏掉了什么。你可以试试这个。

人实体

代码语言:javascript
运行
复制
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String username;

    @OneToMany(mappedBy = "person")
    private List<Phone> phones = new ArrayList<>();

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public List<Phone> getPhones() {
        return phones;
    }

    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }
    //omit getter and setter
}

电话实体

代码语言:javascript
运行
复制
@Entity
@Table(name = "phone")
public class Phone {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "number")
    private String number;

    @ManyToOne(cascade = CascadeType.PERSIST)
    private Person person;

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    //ommit setter and getter
}

电话刀

代码语言:javascript
运行
复制
public interface PhoneDao {
    public Phone save(Phone phone);
}

PhoneDaoImpl

代码语言:javascript
运行
复制
@Repository
public class PhoneDaoImpl implements PhoneDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Phone save(Phone phone) {

        return entityManager.merge(phone);
    }
}

PersonDaoImpl

代码语言:javascript
运行
复制
@Repository
public class PersonDaoImpl implements PersonDao{
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Person save(Person person) {

        return entityManager.merge(person);
    }
}

测试方法

代码语言:javascript
运行
复制
@Test
    @Transactional
    @Commit
    public void say()
    {
        Phone phone = new Phone();
        phone.setNumber("jghjkhk");

        Person person = new Person();
        person.setUsername("7576");

        phone.setPerson(person);
        Phone pers = phoneDao.save(phone);
        Assert.assertNotNull(pers);
    }

现在试一试。看起来不错。

票数 1
EN

Stack Overflow用户

发布于 2018-11-23 16:14:52

我认为您需要设置person->id的值,然后使用getter方法将id传递给您的phone对象,而不是传递person对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53449592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档