Composite Entity update fails

I have a Person object that has a composition with a location object

@ManyToOne(fetch = FetchType.EAGER, cascade =
{ CascadeType.PERSIST, CascadeType.MERGE })
@Cascade(
{org.hibernate.annotations.CascadeType.SAVE_UPDATE })
public Location getLocation()
{
    return location;
}

      

And the Location Entity has a name as Id

@Id
public String getName()
{
    return name;
}

      

I am getting the following exception when Person location changes from L1 to L2 in a Spring MVC form where this Person object is the modelAttribute for the form.

org.springframework.orm.hibernate3.HibernateSystemException: instance id com.xyzLocation has been changed from L2 to L1; Nested Exception - org.hibernate.HibernateException: instance id com.xyzLocation was changed from L2 to L1

+2


source to share


3 answers


You are misleading Composition with Association .

What you have mapped is an association; composition in Hibernate (JPA) is rendered via annotations @Embeddable

/ @Embedded

. Associations are relationships between separate entities; they are usually related through entity identifiers (foreign keys in the database).

In your specific case, the object Person

points to an object Location

, which means that in the database the PERSONS

table has a foreign key LOCATION_ID

(names may differ) from the table LOCATIONS

. What you are trying to do is update this key on the end Location

, which is illegal because it will break the Hibernate relationship (the other end still has the previous key value inside).



Primary keys usually need to be surrogate and non-updatable to begin with; if you need to "update" it, you will have to either disconnect Location

from Person

, or update Location

, or reassign it, Person

or create a new Location

instance and assign it Person

.

All that said, if you are really trying to model composition relationships, you need to replace @ManyToOne with @Embedded and change the table schema accordingly. Here's a link to the Hibernate Annotation Documentation on Component Mapping .

Also, specifying cascading types in two separate annotations (JPA and Hibernate extension) is not very good. If you really need a Hibernate extension (which you are not doing in this case), just use it and leave the attribute cascade

in the JPA annotation blank.

+3


source


I did the same in a standalone app. The thing works. I think this must be a @modelAttribute issue.



0


source


In your id entity object attribute, the type has been changed in your model class . Please refer to the ID and ID of the matching attribute. Make sure the id attribute of the getter and setter functions are both return types.

0


source







All Articles