Hibernate modelling question
I can't solve this the way I want in Hibernate. Here it is: I've a Product, each product has it's own fields and so on. Each product can be either a TopLevelProduct or a SecondaryProduct. A secondary product will be linked to a top level product, a top level product will be linked to nothing. When I query a product from the database I'd like to know if it is TopLevel or not. The list of the linked secondary products can be retrieved later (or even before, but it is not so necessary).
I thought of using this bean:
public class Product{
...properties..
Product topLevelProduct;
...getters and setters...
}
The problem is that if I map the topLevelProduct property as Many-to-One, I have problems deleting top level products. In fact if they have secondary products linked to, I get:
java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`jacciseweb`.`prodotti`, CONSTRAINT `FKC803BB11ACD3B812` FOREIGN KEY (`prodottoDiRiferimento_ID`) REFERENCES `prodotti` (`ID`))
I would expect that if I delete a TopLevelProduct, the se开发者_如何转开发condLevelProducts will be deleted too. Should I use a different structure? Maybe using two beans derived from the same one? Or reversing the relationship like this:
public class Product{
...properties..
List<Product> secondLevelProducts = new ArrayList<Product>();
...getters and setters...
}
This anyway gives me a problem: I have to use another query to know if the product is secondary or not, because just knowing that it has not any secondary product, doesn't mean that it is secondary, it could even be a top level product that has not secondLevel products.
Ideas?
I don't know much about hibernate, but the problem here seems to me quite simple. You can't delete top level products, when an second level product references them.
The solution is to define what should happen to the second level product if you delete the top level. You can cascade the operation (all second level products get deleted). Or the second level products become top level products. There must be a way in hibernate to define the desired behaviour on the association. Search the documentation for something like "cascading delete".
Apart from Marko's answer, if you decided to apply cascade delete when top-level product is removed, you have two options:
If distinction between top-level products and secondary products is stable, i.e. top-level product would never turn into secondary product and vice versa, you can model it as an inheritance hierarchy with a one-to-many relationship between
TopLevelProduct
andSecondaryProduct
(this relationship can be either unidirectional or bidirectional, if you need to access the parent product from the child).Otherwise, you can solve your problem by creating a bidirectional relationship between
Product
s, something like this:public class Product { @ManyToOne private Product topLevelProduct; // Is null for top level products // Applies cascading @OneToMany(mappedBy = "topLevelProduct", cascade = CascadeType.REMOVE) private List<Product> secondaryProducts; ... }
精彩评论