-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Can't get delete orphan to remove the orphan from the db
PostPosted: Tue Jun 14, 2011 6:48 pm 
Newbie

Joined: Tue Jun 14, 2011 6:01 pm
Posts: 1
Using Hibernate 3.3.2 with annotations 3.4.0.

I'm having trouble with cascade delete orphan not working for one particular setup. Other entities in my code base are working just fine. It's the following that isn't working for some reason. I'm just guessing it may have something to do with the fact that the object being orphaned is off of an entity that is mapped in a one-to-one relationship with another entity. This is pure speculation, but it seems to be the only difference between these set of relationships and the other ones I have which do work.

The following is an abbreviated version of our setup with the likely relevant pieces shown.

There are 3 basic objects, an Account, an Allocation which is mapped one-to-one with the account (Every account has one allocation), and a Holding object, which is mapped as a unidirectional one-to-many Set on the Allocation

Account 1-----1 Allocation 1------N Holding

I can't seem to get hibernate to delete a holding once it's removed (and orphaned) from an Allocation object.

Code:
@Entity
@Table("account")
class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
   
    @Version
    int version;   

    @OneToOne(targetEntity = Allocation .class, cascade = {CascadeType.ALL})
    @Cascade({org.hibernate.annotations.CascadeType.ALL,
                     org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    @JoinColumn(name="allocation_id")
    Allocation allocation;
   
    public Allocation getAllocation() {
        return allocation;
    }   
   
    public void setAllocation(Allocation allocation) {
        this.allocation = allocation;
    }   
   
    // ... other methods etc.
}

@Entity
@Table(name="allocation")
class Allocation {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
   
    @Version
    int version;   
   
    @OneToMany(targetEntity = Holding.class, cascade = {CascadeType.ALL}, fetch=FetchType.EAGER)
    @Cascade({org.hibernate.annotations.CascadeType.ALL,
                     org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    @OrderBy("id")
    @JoinTable(name = "allocation_to_holding",
               joinColumns = { @JoinColumn(name = "allocation_id") },
               inverseJoinColumns = { @JoinColumn(name = "holding_id") })
    Set<Holding> holdings = new HashSet<Holding>();   

    public Set<Holding> getHoldings() {
        return holdings;
    }
   
    public void setHoldings(Set<Holding> holdings) {
        this.holdings = holdings;
    }
   
   
    // ... other methods etc.
       
}

@Entity
@Table(name="holding")
class Holding {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
   
    @Version
    int version;       
   
    // ... getters and setters etc.
}



The database schema looks like

Code:
CREATE TABLE  `account` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `version` int(11) NOT NULL,
  `allocation_id` bigint(20) unsigned default NULL,
  ...
  PRIMARY KEY  (`id`),
  UNIQUE KEY `UQ___allocation_id` (`allocation_id`),
  CONSTRAINT `FK_account__allocation__allocation_id` FOREIGN KEY (`allocation_id`) REFERENCES `allocation` (`id`)
)
 

CREATE TABLE  `allocation` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `version` int(11) NOT NULL,
  ...
  PRIMARY KEY  (`id`)
)
 

CREATE TABLE  `holding` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `version` int(11) NOT NULL,
...
  PRIMARY KEY  (`id`)
)

And the link table between allocation and holding

CREATE TABLE  `allocation_to_holding` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `allocation_id` bigint(20) unsigned NOT NULL,
  `holding_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `UQ_allocation_to_holding__holding_id` (`holding_id`),
  KEY `FK_allocation_to_holding__allocation__id` (`allocation_id`),
  CONSTRAINT `FK_allocation_to_holding__allocation__id` FOREIGN KEY (`allocation_id`) REFERENCES `allocation` (`id`),
  CONSTRAINT `FK_allocation_to_holding__holding__holding_id` FOREIGN KEY (`holding_id`) REFERENCES `holding` (`id`)
)





So I can do the following to add holdings from an allocation

Code:
Holding holding = new Holding(...);
account.getAllocation().getHoldings().add(holding);
account = merge(account)
assertTrue(account.getAllocation().getHoldings().size() == 1);


The following (pseudo) code removes the holding from the allocation, but does not remove the holding from the after it's been orphaned from the allocation holdings collection.

Code:
Holding holding = account.getAllocation().getHoldings().iterator().next();

account.getAllocation().getHoldings().remove(holding);
account = merge(account)

// the following is true
assertTrue(account.getAllocation().getHoldings().size() == 0);

// however, should not find the holding
try {
   Holding updatedHolding = get(holding.getId())
   fail("updatedHolding should have been deleted.);
} catch (Exception e) {
// exception should be thrown as holding should be deleted from database after becoming orphaned      
}



Does anyone have any idea if the one-to-one between account and allocation could be affecting things preventing the delete orphan from working? Or any other ideas?

Thanks,
Skip


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.