Asked  6 Months ago    Answers:  5   Viewed   83 times

I receive following error when I save the object using Hibernate

object references an unsaved transient instance - save the transient instance before flushing

 Answers

37

You should include cascade="all" (if using xml) or cascade=CascadeType.ALL (if using annotations) on your collection mapping.

This happens because you have a collection in your entity, and that collection has one or more items which are not present in the database. By specifying the above options you tell hibernate to save them to the database when saving their parent.

Tuesday, June 1, 2021
 
eliotlencelot
answered 6 Months ago
59

I'd expect one of two things to be the reason:

  1. either you don't have Payment listed in your hibernat.cfg.xml or where ever you config your mapped classes.

  2. another reason might be the confusion between javax...Entity and org.hibernate....Entity. Make sure you use the first one.

Friday, June 25, 2021
 
Hilmi
answered 6 Months ago
45

Expanding a bit on the question, there are several situations in which one could need the last object of an array, with different ways to obtain it.

In a straight Cocoa program

If one just wants to get the object in course of a standard Cocoa program, then this will do it:

[myArray lastObject]

To address the concern of the counter - no need to implement one's own, either:

NSUInteger myCount = [myArray count];

Using key-value coding (KVC)

In case one needs to access the last object of an array through KVC, the story requires a bit of explanation.

First, requesting the value of a normal key from an array will create a new array consisting of the values of that key for each of the objects in the array. In other words, a request for the key lastObject from an array will make the array send valueForKey: to each of the objects using the key lastObject on them. Apart from not being the intended result, it will also likely throw an exception.

So in case one really needs to send a key to the array itself (as opposed to its contents), the key needs to be prepended with an @-sign. This tells the array that the key is intended for the array itself, and not its contents.

The key therefore has to have the form @lastObject, and be used like this:

NSArray *arr = @[@1, @2, @3];

NSNumber *number = [arr valueForKey: @"@lastObject"];

In a sort descriptor

An example of how this key could be used in a real program is a situation where an array of arrays needs to be sorted by the last object in each of the inner arrays.

The above key is simply used in the sort descriptor:

NSArray *arrayOfArrays = @[@[@5, @7, @8], @[@2, @3, @4, @6], @[@2, @5]];

NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey: @"@lastObject" ascending: YES];

NSArray *sorted = [arrayOfArrays sortedArrayUsingDescriptors: @[sd]];

In a predicate

Likewise, in order to filter an array of arrays, the key can be used directly in a predicate:

NSPredicate *pred = [NSPredicate predicateWithFormat: @"self.@lastObject > 5"];

NSArray *filtered = [arrayOfArrays filteredArrayUsingPredicate: pred];

People preferring to leave the self-part out can simply use the format @"@lastObject > 5"

Wednesday, July 28, 2021
 
godot
answered 4 Months ago
93

Cascading only makes sense for entity state transitions that propagate from a Parent to a Child. In your case, the Parent was actually the child of this association (having the FK).

Try with this mapping instead:

@Entity
public class Parent {
  ...
  @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
  private Child child;
  ...
}

@Entity
public class Child {

    @OneToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;

    ...
    @Lob
    private byte[] data;
    ...
}

And to cascade the orphan removal, you now need to:

Parent parent = ...;
parent.getChild().setParent(null);
parent.setChild(null);

Or even better, use addChild/removeChild methods in the Parent entity class:

public void addChild(Child child) {
    children.add(child);
    child.setParent(this);
}

public void removeChild(Child child) {
    children.remove(child);
    child.setParent(null);
}
Thursday, July 29, 2021
 
Gersom
answered 4 Months ago
80

Since you are not cascading coupon then you need it to be managed before saving CouponHistory, luckly when saving an entity save() will return the managed persisted entity so all you need is to assign it to coupon

 @Transactional
public void createCoupon() {
Coupon coupon = new Coupon();
coupon.setCode(RandomStringUtils.randomAlphanumeric(5));
coupon.setValidity(1);
coupon = couponRepository.save(coupon);//save will return the managed entity

CouponHistory couponHistory = new CouponHistory();
couponHistory.setCreatedOn(new Date());
couponHistory.setCoupon(coupon);
couponHistoryRepository.save(couponHistory);
}
Sunday, November 14, 2021
 
John Oleynik
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share