繁体   English   中英

对象引用一个未保存的瞬态实例,在刷新之前保存瞬态实例:

[英]Object references an unsaved transient instance save the transient instance before flushing:

表的关系

上图显示了表之间的关系。

AddressType表包含静态值,例如mailinghomework等。

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

您需要将@ManyToOne()更改为@ManyToOne(cascade = CascadeType.ALL)以便保存将尝试级联到 AddressType 然后忽略它,因为您在 @JoinColumn 上设置了insertable=false, updatable=false @JoinColumn =false 。

问题

实体AddressTypeRel将一个表列映射到两个 bean 属性:

  1. int typeId (这在问题中没有明确说明,但您可以从addressTypeRel.setTypeId(j) //j=4 for example推断出来)
  2. AddressType addressType (如问题中明确描述的)

Hibernate 不允许两次映射同一个表列,除非您采取如下所述的必要步骤。

解决方案

这是两步过程,你只做了第一步。 目标是使AddressType addressType (通过其 getter getAddressType()映射)只读,因为 Hibernate 仅在所有其他映射都是只读的情况下才允许多次映射一列

  1. 使AddressTypeRelAddressType之间的关系只读:

    • 正如您已经将其映射为insertable=false, updatable=false一样,但这仅适用于关系而不适用于目标实体
  2. 使目标实体只读,在我们的例子中是AddressType

    • 只需将其标记为@Transient ,此注释将使休眠状态忽略关系的其他实体,并且不会打扰您保存它

讨论

  • 我之前用过insertable=false, updatable=false ,为什么现在出现这个问题? 因为在实体字段上具有读写映射,而在某些原始类型或非实体对象上具有只读映射更为常见。 在这种情况下,您对int进行了读写映射,对实体AddressType进行了只读映射。 当然,您不必在原始类型或非实体对象上使用@Transient注释。
  • 为什么insertable=false, updatable=false不能更智能地检测这些情况? 因为 Hibernate 将两个实体之间的关系视为三部分构造: a)这个实体 b)目标实体 c)它们之间的关系,所以使这个构造只读需要b)c)只读,并且对于两者都有不同的工具来做到这一点(如解决方案中所述)。 这很有用,因为您有更好的控制,例如,您可能希望使目标实体@Transient但不是关系insertable=true, updatable=true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM