我有一个相当简单的一对多关系
[SampleAliasMask] has many [SampleAliasMaskPart]
我的问题当我使用集合部件持久保存SampleAliasMask的新实例时,我得到一个约束违规,即从SampleAliasMaskPart到SampleAliasMask的表的外键链接被设置为NULL。
我正在使用hibernate注释进行映射:
@Entity
@Table(name="SAMPLE_ALIAS_MASK")
public class SampleAliasMask extends ClientEntity {
@OneToMany(mappedBy = "sampleAliasMask", fetch = FetchType.EAGER, cascade = javax.persistence.CascadeType.ALL, orphanRemoval = true)
@Cascade(CascadeType.ALL)
@Length(min = 1, message = "The sample alias mask must have components")
private Set<SampleAliasMaskPart> components;
将关系的另一半映射为:
@Entity
@Table(name="SAMPLE_ALIAS_MASK_PART")
public class SampleAliasMaskPart extends ClientEntity {
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "SAMPLE_ALIAS_MASK_ID", nullable = false)
private SampleAliasMask sampleAliasMask;
ClientEntity的相关部分是
@MappedSuperclass
public abstract class ClientEntity {
@Id
@Column(name="ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
我正在创建这样的部分:
HashSet<SampleAliasMaskPart> components = new HashSet<>();
for(Map<String, Object> c : this.components) {
SampleAliasMaskPart component = new SampleAliasMaskPart(Integer.parseInt(c.get("value").toString(), 10), c.get("name").toString());
result.validate(component);
components.add(component);
}
mask.setComponents(components);
我得到的确切错误是:
java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("ST"."SAMPLE_ALIAS_MASK_PART"."SAMPLE_ALIAS_MASK_ID")
我怀疑这个问题与我从未明确设置SampleAliasMaskPart.sampleAliasMask这一事实有关,但为什么我需要?这种关系永远不会暴露或导航。该字段仅用于映射目的,这使我认为我正在映射这个错误。
答案 0 :(得分:1)
你的假设是正确的。 Hibernate使用关联的拥有方来知道关联是否存在。而拥有的一方是没有mappedBy属性的一方。
一般规则是,当您具有双向关联时,您有责任通过初始化/修改关联的两侧来使对象图形一致。 Hibernate并不关心它,但如果你没有初始化拥有方,它就不会持久存在关联。
请注意,您不必强制将此关联设为双向。如果不这样做,那么将零件添加到面具就足够了,因为这一面(这是唯一的一面)是拥有面。
答案 1 :(得分:0)
JB Nizet建议正确。有两种方法可以解决它:
删除双向关系:从@ManyToOne(optional = false, fetch = FetchType.LAZY)
simpleAliasMask
删除注释SampleAliasMaskPart
通过执行mask
之类的操作,将component
添加到每个component.setSimpleAliasMask(mask)
。这将实现双向关系。