JPA/Spring-boot:键值 'PRIMARY' 重复输入。

5

我正在使用JPA进行mysql操作,但有几次在通过JPA执行mysql保存操作时出现错误。

执行保存操作时出现错误 =>

无法为事务打开JPA EntityManager; 重复条目的主键

表模型类:

@Entity
@Table(name="table_x")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@TypeDefs({
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
})
public class tableX implements Serializable {

    @Id
    @Column(name="product_id")
    private Long productId;

    @Column(name="parent_id")
    private Long parentId;

    // other fields
}

Mysql数据库结构:

 CREATE TABLE `table_x` (
  `product_id` int(12) unsigned NOT NULL,
  `parent_id` int(12) unsigned DEFAULT NULL,
  // other fields
  PRIMARY KEY (`product_id`)
)

代码库类:

@Repository
public interface TableXRepository extends CrudRepository<tableX,Long> {
}

MySQL 操作类:

@Component
@Transactional
public class tableXoperationImpl implements ItableXoperation {

    @Autowired
    private TableXRepository tableXRepository;

    public void save(tableX data) {
        tableXRepository.save(data);
    }
}

我这里是否有遗漏的内容,如果有任何帮助将不胜感激。


1
你能添加更多的日志文件吗?是否有测试或客户端代码的源代码调用ITableXoperation接口?顺便提一下,在Java中类名应该是小写的。 - emeraldjava
你用于执行保存操作的数据是什么?你可能使用了重复的“product_id”。 - Ishara Madhawa
@IsharaMadhawa 我认为,如果您使用相同的product_id保存文档,jpa会在文档已经存在的情况下进行更新而不是插入。 - Amit Kumar
3个回答

2
请在 productId 上使用 @GeneratedValue(strategy = GenerationType.AUTO)

0
在我的情况下,我从CSV中插入了数据,导致hibernate_sequence不同步,这会导致save/saveAll出现问题。
只需编辑hibernate_sequence到最新的id+1,它就应该可以工作了。

0

我认为问题出在你的列product_id,它实际上被定义为表中的主键。

@Id  //this annotation make column as primary key.
@Column(name="product_id")
private Long productId;

您可以自己分配productId,也可以分配一个ID生成策略主键ID生成策略类型

如果您决定自己分配productId,那么它必须是唯一的(在该表(product)的该列中不存在)。

如果您仔细查看异常,您会发现这个Duplicate entry for key 'PRIMARY',这意味着尝试在表(Product)的主键列(product_id)中插入重复值。

或者您可以用以下代码替换上面的主键列。

@GeneratedValue(strategy=GenerationType.AUTO) // automatically generated primary key.
@Id  // Primary key.
@Column(name="product_id")
private Long productId;

谢谢 :)


据我所知,如果您通过JPA再次保存文档,则会更新该文档(如果它已经存在)。 - Amit Kumar
@AmitKumar 是的,没错。但是你应该为主键列分配一个generationType,这可能会解决你的问题。 - Vikrant Kashyap
@AmitKumar 请至少参考一下这个链接 https://www.baeldung.com/spring-data-crud-repository-save - Vikrant Kashyap
Vikrant Kashyap,你好,我不能设置自动生成类型,因为我正在从Kafka管道中获取数据并保存到MySQL中,所以所有参数都来自那里。谢谢你提供的链接,我已经阅读了,我只是想知道为什么JPA保存会抛出错误,在重复文档的情况下应该更新,而且我还执行了将同一文档多次保存的操作测试用例,但我没有收到错误。 - Amit Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接