Issue Details (XML | Word | Printable)

Key: HHH-2292
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Steve Ebersole
Reporter: Mike Youngstrom
Votes: 5
Watchers: 9
Operations

If you were logged in you would be able to see more operations.
Hibernate Core

merge detached instance fails to persist collection changes in case of bare collection reference

Created: 07/Dec/06 10:27 AM   Updated: 24/Jan/07 05:38 PM
Component/s: core
Affects Version/s: 3.2.1
Fix Version/s: 3.2.2

Time Tracking:
Not Specified


 Description  « Hide
I have a ManyToMany relationship. If I attempt to merge a detached instance of the owning side of that relationship the changes to the ManyToMany fail to be persisted. The merge propertly takes place and the persistence context is correctly updated but the SQL commands to update the database are not sent when the session is flushed. I'm using HA 3.2.0 and EM 3.2.0. If I replace the core 3.2.1 jar with 3.2.0 the operation works perfectly. If I attempt the operation on an attached instance the operation works perfectly. it only doesn't work with 3.2.1 with a detached instance. Here are the example entities and example code to duplicate the problem.

--------------Animal.java---------------
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@SuppressWarnings("serial")
public class Animal implements Serializable {

   @Id @GeneratedValue
   private Long id;
    private String name;
    @ManyToOne
    @Basic(fetch=FetchType.LAZY)
    private Classification classification;
    @ManyToMany
    @JoinTable(name="ANIMAL_COUNTRY",
          joinColumns=@JoinColumn(name="ANIMAL_ID"),
          inverseJoinColumns=@JoinColumn(name="COUNTRY_ID"))
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @Basic(fetch=FetchType.LAZY)
    private List<Country> countries;
    @SuppressWarnings("unused")
   @Version
    private Long version;
    
    /** SNIP Getters and Setters **/

}

------------Country.java-----------------
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@SuppressWarnings("serial")
public class Country implements Serializable {

   @Id @GeneratedValue @Column(updatable=false)
   private Long id; //NOPMD - wheelermm
   @Column(unique=true, nullable=false)
    public String name;
    @Basic(fetch=FetchType.LAZY)
    @ManyToMany(mappedBy="countries")
    @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
    public List<Animal> animals;
}


-----------Example code to duplicate problem----------------
//Start Transaction
Animal animal = entityManager.find(Animal.class, 21l);
animal = (Animal)SerializationUtils.clone(animal); // Detach the animal
List<Country> countries = new ArrayList<Country>();
countries.add(countryService.findAllCountries().get(2));
animal.setCountries(countries);
animal.setClassification(entityManager.find(Classification.class, 1l);
animal.setName("Modified Animal");
entityManager.merge(animal);
//Commit Transaction


When the example code above runs both the animal.name and animal.classification are persisted but the change of country is not persisted. the object returned from entityManger.merge() contains the correct country but the db is never updated. if I comment out the clone() (making it not detached) everything works fine. If I downgrade to 3.2.0 everything works fine.

Mike

Forum post: http://forum.hibernate.org/viewtopic.php?t=968226

 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Mike Heath added a comment - 11/Dec/06 04:12 PM
We're having a problem with this too. We would like to upgrade to 3.2.1 but this issues is currently preventing us from doing so. Frankly, I'm surprised more people haven't seen this problem.

Mike Youngstrom added a comment - 12/Dec/06 01:22 PM
One other note. It only seems to not work when a new Collection is created and set in the detached entity. If the existing colleciton is modified:

animal.getCountries().clear();
animal.getCountries().addAll(countries)

then it works fine as well. However, in order to get that to work I had to make the many to many fetch eager for Animal.

Emmanuel Bernard added a comment - 08/Jan/07 06:01 AM
I believe you forgot to set cascade=MERGE, PERSIST on your association (this is at least true for case #1).
I still see something weird when the collection is deferenced.
test in org.hibernate.test.ops.MergeTest#testMergeManyToManyWithColelctionDeference

Steve Ebersole added a comment - 09/Jan/07 08:11 AM
ugh! Somehow when the collection is a "bare reference" the original detached collection collection is being mutated in addition to the merged/persistent collection. I need to find the cause of that, which would probably be the cause. From what I can tell, that is the reson the in memory state is fine after the merge but the merged changes are not persisteted (because after the in memory merge the two collection look the same).

Steve Ebersole added a comment - 09/Jan/07 09:29 AM
Actually has nothing to do with many-to-many; the same should occur with one-to-many or value-collection...

Steve Ebersole added a comment - 09/Jan/07 10:31 AM
trunk / 3.2

Mike Youngstrom added a comment - 13/Jan/07 12:52 PM
Thanks. I just realized the email address I had associated with this jira was bad so I didn't notice you were working on it. I'll verify the fix next week.

Mike

Mike Youngstrom added a comment - 24/Jan/07 05:38 PM
Works great now, thanks.