17

I have two entities: PlayerProfileEntity & UserInfoEntity I have a join on userInfoEntity & PlaterProfileEntity and saving my record in database like this:

Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
Criteria crit = session.createCriteria(PlayerProfileEntity.class);
player.setUserId(new UserInfoEntity());
player.getUserId().setAddress(user.getUserId().getAddress());
session.save(player);
tr.commit();

I used this assosiation in my PlayerProfileEntity class

@ManyToOne (fetch = FetchType.LAZY)
@Cascade({CascadeType.REFRESH})
@JoinColumn(name="userid")

I am getting this error:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save     the transient instance before flushing: com.shared.entity.UserInfoEntity

Note : If i use CascadeType.All, i get this error:

Cannot add or update a child row: a foreign key constraint fails

Any idea how can i solve this

Thanks

Bertrand88
  • 701
  • 6
  • 14
user1226162
  • 1,972
  • 8
  • 27
  • 42

6 Answers6

21

The TransientObjectException comes whenever you try to save the Object without saving the appropriate Joins.You have to save the UserInfoEntity first and afterwards you can save your PlayerInfoEntity class.

player.setUserId(new UserInfoEntity());

By using this you are assigning particular UserInfoEntity to PlayerInfoEntity. But UserInfoEntity does not have any ID. How would both get mapped ? That is why the exception is coming.

Hope it would help you.

Hardik Mishra
  • 14,779
  • 9
  • 61
  • 96
PVR
  • 2,534
  • 18
  • 38
4

You should use the CascadeType.PERSIST or CascadeType.ALL

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • thanks , but i am already using CascadeType.ALL, as mentioned in my question and get the error : Cannot add or update a child row: a foreign key constraint fails , any idea on that – user1226162 Apr 23 '12 at 10:13
  • I'm sorry, didn't see the note in the end. I think, though, we should concentrate on that error you get with CascadeType.ALL. – Marko Topolnik Apr 23 '12 at 10:31
  • You show a line involving `Criteria`, but it's irrelevant to your code. On the other hand, it's missing important code that assembles the `Player` you are going to save. Also, this line is confusing me: `player.getUserId().setAddress(user.getUserId().getAddress())` What's the point of that? And how come UserId is a composite object? – Marko Topolnik Apr 23 '12 at 10:37
  • 1
    If `user` is a persistent object, then his `address` is also persistent. You set that address to the non-persistent object `player`. This could be the cause of your problem. – Marko Topolnik Apr 23 '12 at 10:39
  • thanks , i guess this would be a beginner question , but how player is a non persistent object and how could i make the object player persistent ? thanks – user1226162 Apr 23 '12 at 13:08
  • 2
    It's about the current state of the object as perceived by Hibernate. When you say `session.save(o)`, it's implicitly doing `session.persist(o)` before saving. You can call it yourself, too. At that point Hibernate will "take notice" of your object and enroll it into the session. – Marko Topolnik Apr 23 '12 at 13:23
1
public void savePlayerMethod(PlayerInfoEntity player){

if(player == null){
   player = new PlayerInfoEntity();
}
player.setUserId(getSavedUserInfo());
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(userInfo);
transaction.committ();
}

public UserInfoEntity getSavedUserInfo(){
UserInfoEntity userInfo = new UserInfoEntity();
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(userInfo);
transaction.committ();
}
PVR
  • 2,534
  • 18
  • 38
0

I encountered the same error just now, when trying to store an unsaved object that had an assigned ID through the Session#save() method. I think the problem might be that your unsaved object graph has already been given an id (which is something that the save-method tries to do), and this somehow messes up the cascade of the save-method. Try using Session#persist() instead, cascade should work with this, even though the object has already been assigned an id.

Tobb
  • 11,850
  • 6
  • 52
  • 77
0

I was facing same issue, after lots of debugging i found that removing @AllArgsConstructor from entity and adding

@Tolerate
public <ClassName>() {
}

worked for me.

-1

Well,

I had simmilar problem and what I did was

Object tmp = session.get(Object.class,ob.getId())
if(tmp!=null){
    session.evit(tmp); // or merge
}
session.saveOrUpdate(ob);

This worked for me.

It gets the transient object and evicts it or merges it.

Now use save or update method to save your new object.

Amol Ghotankar
  • 2,008
  • 5
  • 28
  • 42
  • 1
    You need to explain more about this solution. How does evicting then saving solve this problem. Typically this problem is caused by *not* saving an entity attached to the current one being saved. – Randy Stegbauer Apr 23 '12 at 17:18