Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.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 jpa一对多插入重复密钥插入_Java_Hibernate_Jpa - Fatal编程技术网

Java jpa一对多插入重复密钥插入

Java jpa一对多插入重复密钥插入,java,hibernate,jpa,Java,Hibernate,Jpa,我定义了两个具有单向一对多关系的实体: 在Command.class中: 在StockDetails.class中: 表示该命令包含一个StockDetails,StockDetails可以包含在多个命令中,但不包含这些命令 我有两个问题: 当我尝试使用现有StockDetails插入新命令时,我遇到异常,无法在对象中插入重复键。。。 然后我将CascadeType更改为MERGE,然后我没有得到这个异常。 但是,当cascade类型为MERGE时,当我有新的StockDetails,而这些St

我定义了两个具有单向一对多关系的实体:

在Command.class中:

在StockDetails.class中:

表示该命令包含一个StockDetails,StockDetails可以包含在多个命令中,但不包含这些命令

我有两个问题:

当我尝试使用现有StockDetails插入新命令时,我遇到异常,无法在对象中插入重复键。。。 然后我将CascadeType更改为MERGE,然后我没有得到这个异常。 但是,当cascade类型为MERGE时,当我有新的StockDetails,而这些StockDetails在DB中还不存在时,我在 对象引用未保存的临时实例-在刷新之前保存临时实例

当cascade类型为MERGE,并且我在StockDetils中更改了一些详细信息,并插入带有更改的StockDetails的新命令时,这不会更新现有记录 我尝试的示例:

StockDetails sd1 = new StockDetails("GOOL", "Google Inc");
Command c1 = new Command(123456l, 12345614l, sd1, GlobalVeriables.COMMAND_TYPE_ASK, 200, 300d, 1200d,
        new Date(System.currentTimeMillis()), GlobalVeriables.COMMAND_STATUS_OPEN); 
commandManager.addNewCommand(c1);

StockDetails sd2 = new StockDetails("GOOL", "Google Inc LTD");
Command c2 = new Command(5674l, 5678l, sd2, GlobalVeriables.COMMAND_TYPE_ASK, 200, 300d, 1200d,
        new Date(System.currentTimeMillis()), GlobalVeriables.COMMAND_STATUS_OPEN); 
commandManager.addNewCommand(c2);
请帮我解决:

问题1 当我尝试使用现有StockDetails插入新命令时,我遇到异常,无法在对象中插入重复键

我想如果发生以下情况之一,就会发生这种情况:

您已分离StockDetails的实例,或者 手动设置StockDetails的ID,并执行以下操作:

c1.setStockDetails(sd1);
entityManager.persist(c1);
这里发生的情况如下: 实体管理器尝试持久化c1。当CascadeType.PERSIST就位时,它也会尝试在sd1上传播PERSIST操作,以发现数据库中有一个ID相同的条目导致约束冲突异常

解决方案1 及

在本例中,您告诉实体管理器为其分配一个新的sd1未保存实例。现在,实体管理器出现了一个问题:您告诉它在其外键字段中保存StockDetails的id,但是您关联的对象尚未保存,并且没有id,因为您告诉它要传播合并而不是持久化。这就是你得到例外的原因

解决方案2 解决此问题有两种选择:

首先保存sd1,将持久版本分配给c1,并按如下方式保存:

// start transaction
entityManager.persist(sd1);
StockDetails sdPersistent = entityManager.find(StockDetails.class, <id>); // where id is the primary key of the newly saved sd1
c1.setStockDetails(sdPersistent);
entityManager.persist(c1);
// commit transaction

将cascade属性更改为CascadeType.PERSIST,这是本例中更好的选项,请参见上面的解决方案1

c1.setStockDetails(sd1);
entityManager.persist(c1);
// start transaction here
StockDetails sd1 = entityManager.find(StockDetails.class, <id_of_existing_stockdetails>);
c1.setStockDetails(sd1);
entityManager.persist(c1);
// commit transaction here
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name="STOCK_ID", referencedColumnName="id")
public StockDetails getStockDetails() {
    return stockDetails;
}
StockDetails sd1 = new StockDetails("GOOL", "Google Inc");
Command c1 = new Command(123456l, 12345614l, sd1,...);
c1.setStockDetails(sd1);
commandManager.addNewCommand(c1); // assuming this line is saving c1
// start transaction
entityManager.persist(sd1);
StockDetails sdPersistent = entityManager.find(StockDetails.class, <id>); // where id is the primary key of the newly saved sd1
c1.setStockDetails(sdPersistent);
entityManager.persist(c1);
// commit transaction