简体   繁体   中英

Object references an unsaved transient instance save the transient instance before flushing:

表的关系

The diagram shown above shows relation between tables.

The AddressType table contain static values such as mailing , home , work etc.

In AddressTypeRel model class I'm having an AddressType object with annotation many to one

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;
}
......
}

After saving into Address table I should also save the type ( mailing/billing ) of address and addressId into AddressTypeRel but I'm not able to save. While I try to save

AddressTypeRel addressTypeRel=new AddressTypeRel();
addressTypeRel.setAddressId(i) //i=5 for example
addressTypeRel.setTypeId(j)    //j=4 for example
hibernatetemplate.save(addressTypeRel);

The error occuring is :

object references an unsaved transient instance - save the transient instance before flushing: com.sample.AddressType

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

The problem

Entity AddressTypeRel is mapping one table column to two bean properties:

  1. int typeId (this is not explicitly said in the question but you can infer it from addressTypeRel.setTypeId(j) //j=4 for example )
  2. AddressType addressType (as explicitly described in question)

Hibernate does not allow mapping the same table column twice, unless you take necessary steps as described below.

The solution

This is two step process, and you made only the first one. The goal is to make AddressType addressType (mapped via its getter getAddressType() ) readonly, because Hibernate allows mapping one column multiple times only if all additional mappings are readonly .

  1. Making the relationship between AddressTypeRel and AddressType readonly:

    • as you already did you mapped it as insertable=false, updatable=false , but this apply only on the relationship and not the target entity
  2. Making the target entity readonly, in our case it is the AddressType :

    • just mark it @Transient , this annotation will make hibernate to ignore the other entity of the relationship and won't bother you with saving it

Discussion

  • I have used insertable=false, updatable=false before, why am I having this problem now? Because it is far more common to have the read-write mapping on entity field, and have the readonly mapping on some primitive type or non-entity object. In this case you had read-write mapping on int and readonly mapping on entity AddressType . And you don't have to use @Transient annotation on primitive types or non-entity objects of course.
  • Why isn't insertable=false, updatable=false smarter, and detect those cases? Because Hibernate see relationship between two entities as three part construct: a) this entity b) target entity c) the relationship between them , so making this construct readonly requires b) and c) readonly and for both there are distinct tools to do that (as described in solution). This is useful because you have finer control, eg you might want to make the target entity @Transient but not the relationship insertable=true, updatable=true .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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