上图显示了表格之间的关系。
AddressType 表包含静态值,例如邮件,主页,工作等。
在 AddressTypeRel 模型类中,我有一个 AddressType 对象,注释多对一
AddressTypeRel.java
public class AddressTypeRel implements java.io.Serializable{
.......
private AddressType addressType=new AddressType();
.......
@ManyToOne()
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name="typeId", insertable=false, updatable=false, nullable=false)
@NotFound(action = NotFoundAction.IGNORE)
public AddressType getAddressType() {
return addressType;
}
public void setAddressType(AddressType addressType) {
this.addressType = addressType;
}
......
}
保存到地址表后,我还应该保存地址的类型(邮件/结算)和 addressId 进入 AddressTypeRel ,但我无法保存。我试图保存
AddressTypeRel addressTypeRel=new AddressTypeRel();
addressTypeRel.setAddressId(i) //i=5 for example
addressTypeRel.setTypeId(j) //j=4 for example
hibernatetemplate.save(addressTypeRel);
发生的错误是:
对象引用未保存的瞬态实例 - 保存瞬态 刷新前的实例:com.sample.AddressType
答案 0 :(得分:0)
您需要将@ManyToOne()
更改为@ManyToOne(cascade = CascadeType.ALL)
,以便保存将尝试级联到AddressType,然后在insertable=false, updatable=false
上设置@JoinColumn
时忽略它。
答案 1 :(得分:0)
实体AddressTypeRel
将一个表列映射到两个bean属性:
int typeId
(问题中没有明确说明,但你可以从addressTypeRel.setTypeId(j) //j=4 for example
推断出来)AddressType addressType
(如明确所述)Hibernate不允许将同一个表列映射两次,除非您采取如下所述的必要步骤。
这是两个步骤,你只做了第一个。目标是通过只读来AddressType addressType
(通过其getter getAddressType()
映射),因为只有在所有其他映射都是只读的情况下,Hibernate才允许多次映射一列。
只读AddressTypeRel
和AddressType
之间的关系:
insertable=false, updatable=false
,但这仅适用于关系,而不适用于目标实体使目标实体只读,在我们的例子中是AddressType
:
@Transient
,这个注释会让hibernate忽略关系中的其他实体并且不会因为保存而烦恼你insertable=false, updatable=false
,为什么我现在遇到这个问题?因为在实体字段上进行读写映射更为常见,并且具有只读映射在一些原始类型或非实体对象上。在这种情况下,您在int
上具有读写映射,在实体AddressType
上具有只读映射。当然,您不必对原始类型或非实体对象使用@Transient
注释。insertable=false, updatable=false
更聪明,并检测到这些情况?因为Hibernate将两个实体之间的关系视为三部分构造: a)此实体b)目标实体c)它们之间的关系,所以使这个构造只需要 b)和 c) readonly,并且两者都有不同的工具来做(如在解决方案中描述)。这很有用,因为你有更好的控制,例如您可能希望创建目标实体@Transient
,但不能创建关系insertable=true, updatable=true
。