【问题标题】:Duplicate key value violates unique constraint "b_name_key" after save @ManyToOne entity by Spring-boot, Spring-data, HibernateSpring-boot,Spring-data,Hibernate保存@ManyToOne实体后重复键值违反唯一约束“b_name_key”
【发布时间】:2019-09-04 02:05:11
【问题描述】:

保存@ManyToOne 实体后重复键值违反唯一性约束

我试图通过 spring-data 保存一个实体 A,该实体具有另一个具有唯一字段名称的实体 B。如果 B 已经存在于 DB 中,则抛出异常“duplicate key value违反唯一约束“b_name_key”。详情:Key (b_name)=(someName)已经存在。

create table b
(
  b_id         serial primary key,
  b_name varchar(3) not null unique
);

create table a
(
  a_id            serial primary key,
  b_id      int references b (b_id) not null,
);


@Entity
@Getter
@Setter
public class B implements java.io.Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long b_id;
    @Column(name = "b_name", unique = true)
    private String bName;

    public B(String bName) {
        this.bName = bName;
    }

    public B() {}

    @Override
    public String toString() {
        return "...";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        B b = (B) o;
        return Objects.equals(bName, b.bName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bName);
    }
}

@Entity
@Getter
@Setter
public class a implements java.io.Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long a_id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "b_id")
    private B b;


    public a() {
    }

    public a(B b  ) {
        this.b = b;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        a a = (a) o;
        return Objects.equals(b, a.b)
    }

    @Override
    public int hashCode() {
        return Objects.hash(b);
    }
}


@Repository
public interface ARepository extends JpaRepository<Metastasis, Long> {}

@Controller
public class AController {

    private final ARepository aRepository;

    public AController(ARepository aRepository) {
        this.aRepository = aRepository;
    }

    @GetMapping("/test")
    public String showaddUserForm() {
        B b = new B("SomeName");
        A a = new A(b);
        aRepository.save(a);
        return "index";
    }
}

@SpringBootApplication
@EnableJpaRepositories(basePackages = "...repositories")
@EnableTransactionManagement
@EntityScan(basePackages = "....entities")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

我得到 org.postgresql.util.PSQLException:错误:重复键值违反唯一约束“b_name_key” 详细信息:键 (b_name)=(SomeName) 已存在。

【问题讨论】:

    标签: java postgresql hibernate spring-boot jpa


    【解决方案1】:

    这很正常。由于a 实体是新的,PERSIST 操作将级联到同样是新的b 实体,并且由于数据库中已有具有该键的记录而失败。

    尝试类似:

    // find for B
    B b = bRepository.findById(..);
    // if not found, create one
    if (b == null) {
       b = new B("SomeName");
    } 
    A a = new A(b);
    aRepository.save(a);
    

    【讨论】:

    • 为什么hibernate不能自己处理?
    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多