【发布时间】:2011-07-28 10:30:41
【问题描述】:
我的 Hibernate-JPA 域模型具有以下实体:
AttributeType ------< AttributeValue
相关的 Java 类如下所示(省略了 getter 和 setter):
@Entity
public class AttributeType {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true, nullable = false)
private String name;
@OneToMany(mappedBy = "attributeType", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private List<AttributeValue> values = new ArrayList<AttributeValue>();
}
@Entity @Table(uniqueConstraints = @UniqueConstraint(columnNames = {"value", "attribute_type_id"}))
public class AttributeValue {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne(optional = false)
private AttributeType attributeType;
@Column(nullable = false)
private String value;
}
请注意,AttributeValue.value 和 AttributeValue.attributeType 存在唯一约束,因为对于属性类型(例如大小),我们不希望属性值(例如小)出现多次。
如果我通过在单个事务中执行以下操作来更新AttributeType:
- 从“size”属性类型中删除“small”属性值
- 为“size”属性类型添加“small”属性值
我得到一个异常,表明违反了唯一约束。这表明 Hibernate-JPA 在删除之前执行了属性值的插入,这似乎无缘无故地引发了此类问题。
执行AttributeType 更新的类如下所示:
@Transactional(propagation = Propagation.SUPPORTS)
public class SomeService {
private EntityManager entityManager; // set by dependency injection
@Transactional(propagation = Propagation.REQUIRED)
public AttributeType updateAttributeType(AttributeType attributeType) throws Exception {
attributeType = entityManager.merge(attributeType);
entityManager.flush();
entityManager.refresh(attributeType);
return attributeType;
}
}
我可以通过迭代属性值,找出哪些已更新/删除/插入,然后按此顺序执行它们来解决此问题:
- 删除
- 更新
- 插入
但似乎 ORM 应该能够为我做到这一点。我读过 Oracle 提供了一个“deferConstraints”选项,该选项仅在事务完成时才检查约束。但是,我使用的是 SQL Server,所以这对我没有帮助。
【问题讨论】:
-
能否请您显示您的表格的 DDL?可能你没有违反你定义的约束,而是其他一些?
标签: java hibernate jpa persistence