1

我有一个实体要与另一个实体作为多对一关系中的依赖项进行持久化。在构造要持久化的实体实例时,依赖实体总是从 EntityManager 加载。但是,当我尝试持久化实体时,Hibernate 也会尝试插入依赖项,从而导致错误。谁能告诉我为什么会这样以及如何禁用它?

实体定义如下:

@Entity
@Table(name="postal_code")
public class PostalCode implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    PostalCodePK id;

    @MapsId("country")
    @ManyToOne
    @JoinColumn(name="country")
    private Country country;

    public PostalCode(Country country, String code) {
        ...
    }

    ...
}

依赖实体 Country 定义如下:

@Entity
public class Country implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="code_alpha2", columnDefinition="bpchar")
    @Size(min=2, max=2)
    private String codeAlpha2;

    ...
}

构造和持久化实体的相关代码是:

PostalCode postalCode = new PostalCode(em.find(Country.class, "DE"), "01234");
em.getTransaction().begin();
em.persist(postalCode);
em.flush();
em.getTransaction().commit();

当我在 PostalCode 实例上调用 persist 时的日志输出是:

Hibernate: 
    insert 
    into
        Country
        (code_alpha3, code_alpha2) 
    values
        (?, ?)
Aug 05, 2013 11:40:59 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: 23505
Aug 05, 2013 11:40:59 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ERROR: duplicate key value violates unique constraint "country_pkey"
  Detail: Key (code_alpha2)=(DE) already exists.

提前致谢!

4

1 回答 1

0

我遇到了和你一样的问题,这就是我为解决它所做的。

  @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
  @JoinColumn(name = "equityId", referencedColumnName = "id", insertable = false, updatable = false)
  private Equity equity;

这里的关键是,FetchType 是 EAGER 和级联 REFRESH。因为 FetchType 默认是惰性的,由于某种原因它没有被初始化并且它的 null,结果 hibernate 认为它是空的,并在你设置它时尝试插入对象。如果您急切地获取它,则会有一个可以更新的对象。

(您也许可以摆脱另一种级联类型,但这对我有用)

于 2017-09-15T05:10:30.180 回答