当前位置: 首页 > 知识库问答 >
问题:

Spring数据JPA通过从父实体获取id与子实体以及父实体一起插入

微生烨然
2023-03-14

我想通过在父实体上调用保存来将父实体和子实体一起保存到MySQL数据库中。父实体和子实体之间有一对一的映射。父ID是自动生成的,我们需要在子实体中使用与子实体相同的pk。

我使用的是Spring数据JPA2.0(JPA提供程序是Hibernate)和Spring MVC框架。当尝试插入实体时,我遇到以下错误。

根本原因

org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: com.serro.cbmapi.model.Child.parent; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.serro.cbmapi.model.Child.parent org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:207)

这是我的数据库模式:

Parent Table:
   CREATE TABLE `parent` (
   `pid` int(11) NOT NULL AUTO_INCREMENT,
   `parent_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
    PRIMARY KEY (`pid`)    ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;

    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Child Table:
    CREATE TABLE `child` (
    `cid` int(11) NOT NULL,
    `child_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
    PRIMARY KEY (`cid`),
    CONSTRAINT `child_f1` FOREIGN KEY (`cid`) REFERENCES `parent` (`pid`)

    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

以下是我的Java实体父实体:

@Entity(name="parent")
@NamedQuery(name="Parent.findAll", query="SELECT p FROM parent p")
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private int pid;

    @Column(name="parent_name")
    private String parentName;

    //bi-directional one-to-one association to Child
    @OneToOne(mappedBy="parent",cascade=CascadeType.ALL)
    private Child child;

    //getter, setters
}

儿童性:

@Entity(name="child")
@NamedQuery(name="Child.findAll", query="SELECT c FROM child c")
public class Child implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private int cid;

    @Column(name="child_name")
    private String childName;

    //bi-directional one-to-one association to Parent
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="cid")
    @MapsId("cid")
    private Parent parent;

    //getter, setters
}

这是我的主要方法

AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
ParentRepository parentResp = context.getBean(ParentRepository.class);  
Parent parent = new Parent();
parent.setParentName("Parent1");
Child child = new Child();
child.setChildName("Child1");
parent.setChild(child);
parentResp.save(parent);

共有2个答案

司空鸣
2023-03-14

例外

not-null property references a null or transient value: com.serro.cbmapi.model.Child.parent; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.serro.cbmapi.model.Child.parent

表示您的UNICEF对象中的属性为null

因此,要解决这个问题,您需要添加以下代码行:

child.setParent(parent);

同样根据JPA文档:

指定一个多通或一通关系属性,该属性为EmbeddedId主键、EmbeddedId主键内的属性或父实体的简单主键提供映射。value元素指定关系属性所对应的复合键中的属性。如果实体的主键与关系引用的实体的主键的Java类型相同,则不会指定value属性。

子类中声明的父类字段不应包含@MapsId属性:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cid")
@MapsId
private Parent parent;
金成济
2023-03-14

在两个对象中都应该使用级联。试试这个:

@Entity(name="parent")
public class Parent implements Serializable {
    //...
    @OneToOne(mappedBy="parent",cascade=CascadeType.ALL)
    private Child child;
    //...
}

@Entity(name="child")
public class Child implements Serializable {
    //...
    @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name="cid", referencedColumnName = "id")
    private Parent parent;
    //...
}
 类似资料:
  • Javers v5.6.3 我有一个父实体,其中包含一系列子实体。当我区分两个父母列表,发现一个孩子有变化时,我需要知道哪个父母包含变化的孩子。 我的实体: 我想要区分的是: 为了简洁起见,切换到Groovy: 我是如何区分的: 输出: 我的问题是: 如何发现哪个父级包含子级/c1? 除了我有一个老板集合之外,这类似于应该检测薪酬变化()示例。使用该示例,给定具有不同下属的老板列表,如何找出的老板

  • 我的父母子女单向关系如下: 我创建一个父实例,给它分配一个子列表,并尝试持久化它,它工作得很好。 当我试图通过子实体单独保存时,我看到insert查询试图将null插入子表中的列PARENT_ID,并导致 异常,同时保存独立于父表的子实体。我试图插入的子实体与已经存在的父实体相关。 在将关系定义为单向关系后,是否无法直接保存子实体?

  • 我可能需要一些帮助,因为我被这些文件弄糊涂了: 我有一个JPA母公司: 和孩子: 如果我只是增加联系人,我希望JPA能够建立这种关系。 e、 g: 现在发生的是: 触点插入DB(良好) 使用providerX。联系人中的id。提供者列(良好) provider\u contact表中未显示任何关系条目 我知道我可以将联系人设置为提供者的属性<代码>providerX。联系人。添加(c)。。。回购。

  • 如何返回与JPA中的父级有关系的实体列表? 我有一个用户实体,在名为的属性上有@OneToMany映射。子实体为Pet类型。这只是一种单向关系。 如何在JPA中编写返回给定用户的所有宠物的连接?

  • 我正在使用带有mysql数据库的Spring Boot。我想知道如何从父实体分页子实体。 以下是使用案例: 父实体与子实体有单向的一对一关系。下面是一个代码示例: 我需要得到父dateTime在X和Y之间的所有子实体,但要得到子实体的页面。 任何想法如何做到这一点? 我得到了dateTime在X和Y之间的父页面。从这个父页面,我得到了所有父页面的孩子列表,因此来自父母的页面信息与孩子的不一样。 一

  • 我的实体。ValidationStep与documentDetail有一对一的关系,documentDetail与documentValidations有一个完全的关系 我的删除查询 父ValidationStep被删除,但是docDetail和documentValidations仍然在数据库中。