IllegalStateException with Hibernate 4 and ManyToOne cascading

后端 未结 9 2053
梦如初夏
梦如初夏 2020-12-01 16:06

I\'ve got those two classes

MyItem Object:

@Entity
public class MyItem implements Serializable {

    @Id
    private Integer id;
    @ManyToOne(casc         


        
相关标签:
9条回答
  • 2020-12-01 16:23

    Same here, check your equals() method. Most probably is badly implemented.

    Edit: I have verified that a merge operation will not work if you don't implement your Entity's equals() and hashCode() methods correctly.

    You should follow these guidelines for implementing equals() and hashCode():

    http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch04.html#persistent-classes-equalshashcode

    "It is recommended that you implement equals() and hashCode() using Business key equality. Business key equality means that the equals() method compares only the properties that form the business key. It is a key that would identify our instance in the real world (a natural candidate key)"

    That means: You should NOT use your Id as part of your equals() implementation!

    0 讨论(0)
  • 2020-12-01 16:27

    if you are using jboss EAP 6.. change it to jboss 7.1.1 .this is a bug of jboss EAP 6. https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.3/html/6.3.0_Release_Notes/ar01s07s03.html

    0 讨论(0)
  • 2020-12-01 16:30

    Had the same exception (hibernate 4.3.0.CR2) tiring to save a object which is having two copies of a child object, got fixed by, in the entity from :

    @OneToOne(cascade = CascadeType.MERGE)
    private User reporter;
    @OneToOne(cascade = CascadeType.MERGE)
    private User assignedto;
    

    to just,

    @OneToOne
    private User reporter;
    @OneToOne
    private User assignedto;
    

    i don't know the reason though

    0 讨论(0)
  • 2020-12-01 16:30

    If name is the Id why are you creating two objects with the same id?? you can use the c1 object in all the code.

    If that's only an example and you create the c2 object in another part of the code, then you shouldn't create a new object but load it from database:

    c2 = itemDao.find("comp", Component.class); //or something like this AFTER the c1 has been persisted
    
    0 讨论(0)
  • 2020-12-01 16:35

    Is your relationship between item and component unidirectional or bidirectional? If it's bidirectional make sure you don't have Cascade.MERGE calls going back up to Item.

    Basically, the newer version of Hibernate has a entity map that contains a list of all things that need to be merged based on the call to merge() it will call merge and then move onto the next one, but keep things in the map, it will throw the error you state above "An entity copy was already assigned to a different entity" when it encounters an item that has already been dealt with. We found in our app when we located these "upward" merges in the object graph ie. on bidirectional links, it fixed the merge call.

    0 讨论(0)
  • 2020-12-01 16:41

    I had the same problem, and this is what I found:

    The merge method traverses the graph of the object that you want to store, and for each object in this graph it loads it from the database, so it has a pair of (persistent entity, detached entity) for each object in the graph, where detached entity is the entity that is going to be stored, and persistent entity is gotten from the database. (In the method, as well as in the error message the persistent entity is known as 'copy'). Then these pairs are put in two maps, one with the persistent entity as key and the detached entity as value, and one with the detached entity as key and the persistent entity as value.

    For each such pair of entites, it checks these maps, to see if the persistent entity maps to the same detached entity as before (if it has already been visited), and vice versa. This problem occurs when you get a pair of entities where doing a get with the persistent entity returns a value, but a get from the other map, with the detached entity returns null, which means that you have already linked the persistent entity with a detached entity with a different hashcode (basically the object identifier if you have not overridden the hashcode-method).

    TL;DR, you have multiple objects with different object identifiers/hashcode, but with the same persistence identifier (thus referencing the same persistent entity). This is appearantly no longer allowed in newer versions of Hibernate4 (4.1.3.Final and upwards from what I could tell).

    The error message is not very good imo, what it really should say is something like:

    A persistent entity has already been assigned to a different detached entity

    or

    Multiple detached objects corresponding to the same persistent entity

    0 讨论(0)
提交回复
热议问题