Java Spring数据JPA通过从父实体获取id插入子实体和父实体

Java Spring数据JPA通过从父实体获取id插入子实体和父实体,java,hibernate,spring-data-jpa,parent-child,jpa-2.0,Java,Hibernate,Spring Data Jpa,Parent Child,Jpa 2.0,我想通过调用save on Parent将父实体和子实体一起保存到MySQL数据库中。父实体和子实体之间存在一对一映射。父ID是自动生成的,我们需要在子ID中使用相同的ID作为子pk 我使用的是SpringDataJPA2.0(JPA提供程序是Hibernate)和SpringMVC框架。 当尝试插入实体时,我遇到以下错误 根本原因 以下是我的数据库模式: Parent Table: CREATE TABLE `parent` ( `pid` int(11) NOT NULL AUT

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

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

根本原因

以下是我的数据库模式:

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);
例外

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
表示
子对象中的
父属性
null


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

child.setParent(parent);
此外,根据:

指定一个多通或一通关系属性,该属性 提供EmbeddedId主键(属性)的映射 在EmbeddedId主键或 父实体value元素指定 关系属性对应的复合键。如果 实体的主键与主键的Java类型相同 对于关系引用的实体,value属性为 未指定。

应声明
子类中的
父类
字段,而不使用
@MapsId
属性:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cid")
@MapsId
private Parent parent;

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

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