1

Relation of table

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

Cijo
  • 345
  • 3
  • 5
  • 10
  • Is `AddressType` also saved before `hibernatetemplate.save(addressTypeRel);`. It seems to me you are trying to point to an address type (here: `addressTyperel.setTypeId(j);`) id which is not saved on the db. – ThanksForAllTheFish Jan 21 '13 at 12:42
  • @mardavi Actually **AddressType** table contains values already. It is a static table with various address types _1.mailing_, _2.home_ etc. We are just saving the Ids of **AddressType** table to **AddressTypeRel** – Cijo Jan 21 '13 at 13:01
  • From your question it is not apparent that you are mapping one table column to two properties (i.e. `int getTypeId()` and `AddressType getAddressType` both pointing to `typeId` column), please fix that. – Vlastimil Ovčáčík May 29 '16 at 09:40
  • Does this answer your question? [How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error](https://stackoverflow.com/questions/2302802/how-to-fix-the-hibernate-object-references-an-unsaved-transient-instance-save) – Jens Schauder Feb 11 '21 at 07:37

2 Answers2

0

You need to change @ManyToOne() to @ManyToOne(cascade = CascadeType.ALL) so the save will attempt to cascade to AddressType and then ignore it as you have insertable=false, updatable=false set on @JoinColumn.

Thomas Inman
  • 95
  • 1
  • 10
  • I tried this, it does not work. The truth is that `insertable=false, updatable=false` were not ignored, and hibernate was aware of them. They would be applied and the column would not be inserted/updated if another exception (unrelated to `insertable` and `updatable` attributes) didn't occur: `object references an unsaved transient instance - save the transient instance before flushing`. – Vlastimil Ovčáčík May 29 '16 at 09:37
0

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, e.g. you might want to make the target entity @Transient but not the relationship insertable=true, updatable=true.
Vlastimil Ovčáčík
  • 2,799
  • 27
  • 29