我有一个实体与另一个实体持久化作为多对一关系中的依赖关系。在构造要保留的实体的实例时,始终从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) {
...
}
...
}
依赖实体国家/地区定义如下:
@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实例上调用持久化时的日志输出是:
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.
提前致谢!
答案 0 :(得分: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认为它是空的并且在设置它时尝试插入对象。如果你急切地获取它,会有一个对象可以更新。
(你可能能够逃脱另一种级联类型,但这对我有用)