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

jpa一对多插入重复键插入

姬自强
2023-03-14

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

在command.class中:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="STOCK_ID", referencedColumnName="id")
public StockDetails getStockDetails() {
    return stockDetails;
}

在StockDetails.class中:

@Id
public String getId() {
    return id;
}
    null
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个答案

沈子实
2023-03-14

当我尝试用现有的StockDetails插入新命令时,我在“无法在对象中插入重复键...”上遇到异常。

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

>

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

    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
    

    在本例中,您告诉实体管理器持久化c1并为其分配一个新的sd1(未保存的实例)。现在实体管理器遇到了一个问题:您告诉它在其外键字段中保存stockDetails的id,但是您关联的对象还没有保存并且没有id(因为您告诉它传播MERGE,而不是PERSIST)。这就是为什么你会得到例外的原因。

    您有两个解决问题的选项:

    >

  • 首先保存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
    

  •  类似资料:
    • 问题内容: 我了解存在和。但是,当有重复的键时,我想对临时表进行操作,以记录已违反的唯一键的记录,以便将其输出给用户。 有什么办法可以做吗?如果有帮助,我正在尝试进行批量插入。 问题答案: 使用,您不能插入到另一个表中-也没有可用的替代功能。 您可以通过两种自定义/替代方式来实现此目的: 使用对此问题的可接受答案中概述的:将MySQL ON DUPLICATE KEY插入到审计表或日志表中 创建一

    • 我正在使用Envers来审核表,但它正在为未知/不存在的表创建一些审核表。它看起来像多对一关系的多对多关系审计表。 这是对的吗?如果是,为什么? 但当我尝试删除和HorarioFixo时,我遇到了一个错误。 我收到的错误: 这是SQL重复: 所有这些都是代码的一部分。如果你需要更多,请留下评论。 我的班级: 我的映射: 新罕布什尔州和恩维尔斯配置:

    • 问题内容: 我正在执行插入查询,其中如果已经存在唯一键,则许多列中的大多数都需要更新为新值。它是这样的: 我不确定该子句的语法应该是什么。如何从子句引用当前行? 问题答案: MySQL将假定等号之前的部分引用INSERT INTO子句中命名的列,而第二部分引用SELECT列。

    • 问题内容: MySQL有这样的东西: 据我所知,SQLite中不存在此功能,我想知道的是,是否有任何方法可以实现相同的效果而不必执行两个查询。另外,如果这不可能,那么您更喜欢什么: SELECT +(插入或更新) 或 UPDATE( 如果UPDATE失败,则 + INSERT ) 问题答案: 因为3.24.0 SQLite还支持upsert ,所以现在您可以简单地编写以下内容

    • 我的意图是创建4个Emp对象。2个对象(e1和e2)具有相同的哈希代码。因此,当插入e1(插入在e2之后)时,hashmap会意识到具有相同哈希值的对象已经存在(对象e2)。然后它会将槽中所有对象的键与相同的哈希值进行比较。如果它找到一个具有匹配键的对象(通过调用下面Emp类的equals方法),它将用新值替换旧值。 下面请看一下测试代码: 我期望的输出:替换的记录名称:Terry,年龄:60名称

    • 问题内容: 我有一张桌子,就是PK。当我插入行时,将有重复的键,并且我需要总结三个统计信息。我在Java中对PreparedStatement使用以下查询: 是否有更简洁的查询来实现?因为我简化了查询,所以那里有十多个统计信息。 问题答案: