【问题标题】:Hibernate persisting Set of @Embeddable objects throws exceptionHibernate 持久化 @Embeddable 对象集抛出异常
【发布时间】:2016-05-02 16:36:39
【问题描述】:

我的课程与此类似:(Offer 课程)

@Entity
public class Offer {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;
    @ElementCollection(fetch = FetchType.LAZY)
    private Set<Product> products;

    ...other fields
}

和产品类别:

@Embeddable
public class Product {
    private String name;
    private String description;
    private int amount;
}

问题是当我尝试持久化 Offer 实体并尝试将两个对象添加到 Offer 的 Set 时:

Product product = new Product("ham", "description1", 1);
Product product = new Product("cheese", "description2", 1);

我收到异常:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "offer_products_pkey"
  Details: Key (offer_id, amount)=(1, 1) already exists.

我不知道为什么当其中一个具有相同的“金额”字段值时,我不能在 Set 中保留两个可嵌入对象?是否以某种方式被视为 ID?

也许我不应该创建可嵌入对象列表,因为它不是为这样使用而设计的?如果是这样 - 那么如果我不需要 Product 的实体但想将其保留在另一个实体(Offer)中怎么办?

提前感谢您的帮助

【问题讨论】:

  • 您可能在表 Products 中定义了错误的键。例外很明显
  • 我在 Product 对象中没有任何关键变量。如果我使用 List 而不是 Set 它可以正常工作,但对于 Set 它不会。问题似乎与 Set 接口的功能有关 - 它不能包含重复项。但是为什么字段“金额”被视为重复?
  • 错误来自PostgreSQL。它告诉您出了什么问题:您已经为 (offer_id, amount) 定义了一个名为 offer_products_pkey 的主键。并且您正在尝试插入具有相同主键的两行。如果该主键约束不应该存在,则删除它。

标签: java hibernate jpa exception embeddable


【解决方案1】:

使用Set 时的问题是内容必须是唯一的,因为这是Set 的定义。 JPA 提供者将尝试使用数据库约束来强制执行此操作。在您的示例中,它以Primary KeyOffer_id 和 int Amount 的形式添加了一个约束,尽管恕我直言,它应该为 Product 属性的所有值添加一个约束。查看这一点的最佳方法是启用 SQL 日志并查看幕后情况:

Hibernate: create table Offer (id integer not null, primary key (id))
Hibernate: create table Offer_products (Offer_id integer not null, amount integer not null, description varchar(255), name varchar(255), primary key (Offer_id, amount))
Hibernate: alter table Offer_products add constraint FKmveai2l6gf4n38tuhcddby3tv foreign key (Offer_id) references Offer

解决此问题的方法是将Offerproducts 属性设为List 而不是Set

Hibernate: create table Offer (id integer not null, primary key (id))
Hibernate: create table Offer_products (Offer_id integer not null, amount integer not null, description varchar(255), name varchar(255))
Hibernate: alter table Offer_products add constraint FKmveai2l6gf4n38tuhcddby3tv foreign key (Offer_id) references Offer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多