3

I'm trying to persist a User that has a mapping @ManyToOne with UserStatus

but when I do the code below, the hibernate throws PropertyValueException

user.setStatus(new UserStatus(1));
em.persist(user); // ou session.saveAndUpdate(user);

to work I have to do this way:

user.setStatus(em.getReference(UserStatus.class, 1));
em.persist(user); // ou session.saveAndUpdate(user);

I know the first way is possible, but what I don't know is whether I need to configure or call another method (I've already tried saveAndUpdate from Session and still the same)

Does anyone have any idea?

The error message is:

not-null property references a null or transient value

the mapping

@ManyToOne(optional = false)
@JoinColumn(name = "user_status_id", nullable = false)
public UserStatus getStatus() {
    return status;
}
SoWhat
  • 5,204
  • 2
  • 24
  • 54
Sergio Marcelino
  • 1,072
  • 8
  • 15

1 Answers1

1

This error means "you are referencing a null (not persisted) object" and you have to choice: remove nullable or set @Cascade so UserStatus will per persisted when you do em.persist(user)

@ManyToOne(optional = false)
@JoinColumn(name = "user_status_id", nullable = false)
@Cascade(cascade=CascadeType.ALL)
public UserStatus getStatus() {
    return status;
}

EDIT: After various test, using getReference() is the right way to proceed because new UserStatus(1) go for error and should be substituted as getReference(UserStatus.class,ID) to return a proxied instance of UserStatus. Proxied object doesn't hit on database, so SELECT is avoided and the only field setted on UserStatus proxy is the ID, necessary to resolve @ManyToOne relation!

Some useful answer: When to use EntityManager.find() vs EntityManager.getReference()
What is the difference between EntityManager.find() and EntityManger.getReference()?

Community
  • 1
  • 1
Luca Basso Ricci
  • 16,612
  • 2
  • 40
  • 61
  • the relation entity is already persisted on the database, however the object isn’t attached, I don’t want to do a SELECT just to make a INSERT – Sergio Marcelino Aug 07 '13 at 15:13
  • so just try to remove `nullable` – Luca Basso Ricci Aug 07 '13 at 15:18
  • if I remove nullable the hibernate tries to INSERT null in this column, which is NOT NULL on the database – Sergio Marcelino Aug 07 '13 at 15:24
  • you have to do a SELECT because Hibernate - with error `not-null property references a null or transient value` doesn't allow transient objects (created with `new`) – Luca Basso Ricci Aug 07 '13 at 15:28
  • It's not mandatory. Doing the getReference doesn't make any SELECT statement and it works fine. But I know there's a solution for this, just setting the ID on the association – Sergio Marcelino Aug 07 '13 at 16:55
  • `getReference()` just set ID on the association because it's return a UserStatus proxy without hit database (in proxied object just the ID is retrieved): `getReference()` is the right way to do what you wrote on your last comment (_But I know there's a solution for this, just setting the ID on the association_)! http://stackoverflow.com/questions/1607532/when-to-use-entitymanager-find-vs-entitymanager-getreference http://stackoverflow.com/questions/5482141/what-is-the-difference-between-entitymanager-find-and-entitymanger-getreferenc – Luca Basso Ricci Aug 07 '13 at 17:53
  • I know that, but in the company I work we do "user.setStatus(new UserStatus(1))" without the need to create a proxy and it works fine, I already asked how it is done, but no one knows the answer. – Sergio Marcelino Aug 07 '13 at 20:08