Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring JPA/Hibernate@manytone关系始终插入子行_Java_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Java Spring JPA/Hibernate@manytone关系始终插入子行

Java Spring JPA/Hibernate@manytone关系始终插入子行,java,hibernate,jpa,spring-data-jpa,Java,Hibernate,Jpa,Spring Data Jpa,我正在尝试使用Spring JPA/Hibernate来维护一个父表,该父表具有一个基于Id的相关子表。如果我尝试插入同一对象两次,父表将正确地“更新”,但即使子表中的条目已经存在,子表也始终被插入到 CREATE TABLE `parent_table` ( `parent_id` int(11) NOT NULL AUTO_INCREMENT, `ex_column_1` int(11) NOT NULL, // there is a unique constraint on thi

我正在尝试使用Spring JPA/Hibernate来维护一个父表,该父表具有一个基于Id的相关子表。如果我尝试插入同一对象两次,父表将正确地“更新”,但即使子表中的条目已经存在,子表也始终被插入到

CREATE TABLE `parent_table` (
  `parent_id` int(11) NOT NULL AUTO_INCREMENT,
  `ex_column_1` int(11) NOT NULL, // there is a unique constraint on this field - I just didn't include it
  `ex_column_2` int(11) NOT NULL,
  `child_id` int(11) NOT NULL,
  PRIMARY KEY (`parent_id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
子表:

CREATE TABLE `child_table` (
  `child_id` int(11) NOT NULL AUTO_INCREMENT,
  `child_col_1` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`child_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
POJO:

@Entity
@Table(name = "parent_table")
public final class Parent {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "parent_id")
    private long id;

    @Id
    @Column(name = "ex_column_1")
    private int exampleField;

    @Column(name = "ex_column_2")
    private int exampleField2;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "child_id", unique = true)
    private Child c;

    public Parent(/*params*/) {}

    // getters ...

    @Entity
    @Table(name = "child_table")
    public static final class Child {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "child_id")
        private long id;

        @Column(name = "child_col_1")
        private exampleChildField;

        public Child(/*params*/) {}

        // getters ...
    }
}
如何构造和保存POJO的实际示例:

@RestController
@RequestMapping("/parents")
public final class ParentController {
    private final ParentRepository parentRepository;

    @Inject
    public ParentController(final ParentRepository parentRepository) {
        parentRepository = parentRepository;
    }

    @RequestMapping(value = "", method=RequestMethod.PUT)
    public void updateParents(@RequestBody Parent[] parents) {

        // ignore input for now, test by constructing object

        Parent.Child c = new Parent.Child(0L, "test 1");
        Parent p = new Parent(0L, "unique_column_1", "column_2", c);
        Set<Parent> pSet = new HashSet<>();
        pSet.add(p);

       parentRepository.save(pSet);
    }
}
第二次插入时:

Hibernate: insert into child_table (child_col_1) values (?)
Hibernate: update parent_table set ex_column_2=?, child_id=? where ex_column_1=? 

如果条目已经存在,如何让EntityManager正确保存这些内容?

我想我已经发现了问题。默认情况下,用于将新“父”对象发布到rest接口的客户端将主键ID设置为0。这对父级有效,因为ex_column_1是一个ID,它在通过其他机制创建对象时是已知的


另一方面,子对象只有一个主键作为其Id,通过将其设置为零,Spring尝试基于零的Id查找相关的子行,并且如果子行已经存在,则总是执行插入而不是更新。在两个对象上使用EntityManager.find()方法进行简单检查,然后保存或合并,可以修复此问题。

您有一个奇怪的数据库。每个家长只有一个孩子,在这种情况下,应该是一个一个而不是多个一个。我已经把这个例子简化为一个尽可能简单的例子,但在实际的用例中,子表中的一个条目可能有多个父表条目。请在创建要持久化的实体的位置发布代码。能否显示一些用于插入和更新数据库的代码?最好是一个JUnit测试,因为创建实体的代码实在不多。这些对象是使用一些伪数据创建的。我将更新我的示例以显示它们是如何构造的。我有一个惊人的怀疑,因为子id为0,Spring试图查询该表以查找id为0的行,但找不到该行,因此执行插入。正确的问题可能是,如何正确查询第二个表,使其得到更新,而不是作为新行插入?
Hibernate: insert into child_table (child_col_1) values (?)
Hibernate: insert into parent_table (ex_column_1, ex_column_2, child_id) values (?, ?, ?)
Hibernate: insert into child_table (child_col_1) values (?)
Hibernate: update parent_table set ex_column_2=?, child_id=? where ex_column_1=?