【问题标题】:JPA: primary key violation when saving an entity with many to oneJPA:保存具有多对一的实体时违反主键
【发布时间】:2017-06-20 10:14:49
【问题描述】:

我有 2 个 JPA 实体

@Entity
@Data
public class Config {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String data;

    @ManyToOne(cascade= CascadeType.ALL)
    private Tenant tenant;
}


@Entity
@AllArgsConstructor
class Tenant {  
    @Id
    private String tenantID;
}

还有一个仓库

interface SolmanConfigPrivateRepository extends CrudRepository <Config, Long> {

}

我使用以下代码创建新实体

public void addConfig(Config config){
    String tenantId = userProvider.get();
    config.setTenant(getCurrentTenant());
    Tenant tenant = new Tenant(tenantId);
    dbRepository.save(config);

}

我设法使用存储库的保存方法保存了一个配置。

如果我尝试使用同一租户保存新配置,则会收到错误消息

 Unique index or primary key violation: "PRIMARY_KEY_9 ON PUBLIC.TENANT(TENANTID)

如果数据库中已有另一个租户,我如何告诉 JPA 不要尝试创建新租户(而是引用现有租户)?

【问题讨论】:

  • 显示构造实体和调用保存的方法
  • 我编辑了我的问题

标签: java jpa


【解决方案1】:

您违反了休眠会话。你需要做的是,通过 id 从数据库中findTenant,设置从数据库中提取的实体(那个特定的引用)然后保存。否则,Hibernate 将尝试保存而不是更新。

public void addConfig(SolManConfig solManConfig){
    String tenantId = userProvider.get();
    solManConfig.setTenant(getCurrentTenant());
    Tenant tenant = tentantRepository.findOne(tenantId);
    dbRepository.save(solManConfig);
}

Spring data JPA 有一种保存和更新的方法。是保存。当您传递一个新对象时,它会保存,否则会更新。 “新对象”是什么意思?这意味着,一个尚未从数据库中提取的对象。

【讨论】:

  • 租户租户 = tentantRepository.findOne(tenantId);对 solManConfig 没有任何作用。您的意思是:租户租户 = tentantRepository.findOne(tenantId); solManConfig.setTenant(租户); dbRepository.save(solManConfig); ?
  • @hipokito 确实如此。您需要设置级联并最终刷新实体
【解决方案2】:

tenant id是怎么设置的?明显不是生成的(根据JPA注解),所以我猜你是手动设置的?

如果您根本不设置它,则tenantID 将为null,因此在插入另一个租户(然后也具有tenantID null)时,唯一约束会被违反的。

【讨论】:

  • 我通过构造函数手动设置(我刚刚编辑了我的问题)
猜你喜欢
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 2019-07-01
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多