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

时间:2013-01-21 12:35:24

标签: hibernate

Relation of table

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

问题

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

  1. int typeId(问题中没有明确说明,但你可以从addressTypeRel.setTypeId(j) //j=4 for example推断出来)
  2. AddressType addressType(如明确所述)
  3. Hibernate不允许将同一个表列映射两次,除非您采取如下所述的必要步骤。

    解决方案

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

    1. 只读AddressTypeRelAddressType之间的关系:

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

      • 只需标记@Transient,这个注释会让hibernate忽略关系中的其他实体并且不会因为保存而烦恼你
    3. 讨论

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