aspose file tools*
The moose likes Object Relational Mapping and the fly likes hibernat creating the tables without cascade Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "hibernat creating the tables without cascade" Watch "hibernat creating the tables without cascade" New topic
Author

hibernat creating the tables without cascade

taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
hii guys,
i'm using hibernate annotations in my project,
I've created the tables and it's all good except that when i check the database their's no cascade even tho I've made sure to put it in the classes.
here is an exemple of how i do it :


i'm using mysql database, here's the hibernate.cfg.xml:


and the application-context.xml:


what am i doing wrong ?
thank you!
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

except that when i check the database their's no cascade


Not a very helpful description of the problem. Perhaps you could explain what behaviour you are expecting and what actually happens using a simple example. It may also be useful to see your EntityManager code.
William P O'Sullivan
Ranch Hand

Joined: Mar 28, 2012
Posts: 859

I think what he means is that when he examines the database table, there is no ON CASCADE defined as a constraint.

It would be helpful to see the full DDL though.

WP
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
yes it is like William P O'Sullivan said there is no ON CASCADE defined as a constraint.
here's the DDL:



like i said i only gave one examble of the entity, because i use the same logic in them all so their is no point of repeating.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

Some of the attributes are used only for schema generation like your @Column(length = xxx) . Cascade is not one of those attributes. This is not used for schema generation, rather it defines how operations are propagated to the associated entity. This is different than adding a cascade on delete option on a database ddl. For example there is a CascadeType.PERSIST which clearly has no equivalent in a database schema.


[How To Ask Questions][Read before you PM me]
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
okey so what attributes should i add to get the cascad option.
i forgot to add that i already tried
@OnDelete(action = OnDeleteAction.CASCADE)
and
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

I generally don't generate the ddl so I have not really had this issue, but It looks like @OnDelete should work for this, make sure it is on the parent entity, you can try explicitly defining the FK with @ForeignKey as well.

Here is a blog on it:
http://deprecatedconsciousness.wordpress.com/2009/11/25/cascade-delete-foreign-keys-using-hibernate-hbm2ddl/

I would probably become familiar with what that annotation does as well. Read here for that:
http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
:s still no cascade but thank you for the links, learned a couple of new things .
i think i might do this manually (delete the parent befor the child object) their's so much changes that happen so the database should be possible to generate from the classes.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

Using the cascade annotations are still beneficial. Not sure what you meant by do it all manually.

Just to throw a shallow example out there say I have a Person entity and an Address Entity. Say the Person has an Address.

One possible mapping might look something like this


Now without the CascadeType.PERSIST I would have to save the address before saving the person. Now I can just create the person set a new address on it and save the person. This will automatically save the address first for me, avoiding the need to call save on each of the objects. Of course there are the others you were talking about to:

CascadeType.REMOVE, Orphan remval and OnDelete. Even if it does not go in your ddl it can save you a lot of work in your code if you can call persist or delete and hibernate will take care of issuing the correct sql to persist or remove the associated entities.

Good Luck,
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
but doesn't cascade = CascadeType.ALL cover them all (persist, remove ...). the reason why i'm cheking the DDL is because when i delete the adresse in your example (knowing that it's attached to a person)
I will end up with an foreing key error : Cannot delete or update a parent row: a foreign key constraint fails (`dac_bd4`.`item`, CONSTRAINT `FK317B1335EE5A98` FOREIGN KEY (`IDDIVISION`) REFERENCES `division` (`IDDIVISION`))

here is the entire error log:



when i said i'll do it manually i mean befor deleting the adresse i'm going to delete every person that has that adresse then delete the adresse (i realise it's not the best way to do it :s ... ).
thank you for your time!

Edit - Removed long lines to prevent horizontal scrolling
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

If your cascade works correctly, you won't need to delete the address after deleting the person. The first delete should delete both entities. This is assuming no other person is linked to the address.
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
that precisely the probleme, cascade is not working and i can't figure out why!
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

Hang on, I now realise your problem.

You are trying to delete an Item which has a ManyToOne relationship with a Division - meaning more than one Item can refer to the same Division. On this relation, you have also defined a Cascade type of ALL. The error you are getting is because another Item (or multiple Items) refers to the Division you are trying to delete - via the cascade when deleting an Item.

Either your relation is incorrect or you need to change your cascade type.
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
actualy a get the error when i try to delete the division and yes many item can refere to the same division so when i try to delete a division all the items atached to it are deleted as well.
change my cascade type to what exactly? like i'v said i alredy tried a few and no luck.
excuse my questions, this is my first time with an ORM
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

Ok, can you post the code for the Division class? Specifically, how is the relation to an Item defined in this class.
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
okey her's the code for the class division:

the class item again:



and finaly a division can contain 0 or many items. voila
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

Ok, so you have no cascade defined in Division for Item. This explains why when you attempt to delete a Division, no cascade occurs but the error is raised because one or more Items refers to the Division you are attempting to delete. You cannot expect anything to happen to your Items when you delete a Division unless you define it as such in the Division class.

I believe the only way to do this is to apply a OneToMany relation in Division for Item with a cascade type of ALL and DELETE_ORPHAN.

Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

but doesn't cascade = CascadeType.ALL cover them all


It does not include orphan removal that is different.

Ill be honest I typically use JPA with hibernate as the persistence provider thusly I only use the cascade options from that javax.persistence package only.

You need to be careful with REMOVE

The cascade REMOVE operation really only makes sense on one-to-one and one-to-many relationships where there is a clear parent-child relationship. What I mean by that is even if it is a one-to-one or a one-to-many if the target is participating in other relationships or can stand alone it probably does not make sense to use REMOVE.

That said consider the following.. (Note that if the owning side is safe for REMOVE it is probably also safe to use PERSIST however the inverse is NOT necessarily true)



This will remove the Employee and his cubicle. Cascade.REMOVE can only safely be cascaded from parent to child. Trying to remove the Cubicle directly will result in an integrity constraint violation unless I first set reference to the Cubicle in the employee object to null. Setting the REMOVE cascade option on the @OneToOne annotation in the Cubicle object would not cause it to be removed from the Employee rather it would have the undesirable affect of removing the employee. As you know removing a cubicle should not remove the employee.

Hope this clears things up for you.


taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
okey so i'm back, i tried to apply a OneToMany relation in Division for Item like james said but it didn't change anything i'm still getting that Cannot delete or update a parent row error, i alse made sur i have the CascadeType.Persist
here is how it looks now


and division:
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1030
    
    5

Probably best to keep it simple for now. Remove all cascade-related annotations in the Item class and only have CascadeType.ALL in Division class. Also remove OnDelete annotation.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

OK I am not sure if you just did not read my last post or if you did not understand it.

As James said lets simplify this and keep it just about Cascade.REMOVE for moment.

Say you have this in your Division (Note that having both CascadeType.ALL and cascadeType.REMOVE is redundant)


Now like you example lets have this for Item


Now lets take a look at a simple example.



Ok so far so good. Now lets try to delete an Item. This is where I think you ignored my last post


Ok so to summarize. Running this with the Cascade.REMOVE on the @ManyToOne has the undesirable effect of deleting all the items and the division!! Taking the cascade.Remove off will result in an exception. Lets modify the code now so that it will work. It now looks like this. The cascade rules are the same on the @OneToMany




Ok now hopefully you understand Cascade.Remove.

Lets talk about orphan removal. Orphan removal should only be used on a very specific type of parent child relationship. It can only be added on @OneToMany and @OneToOne.

Orphan removal rules:
rule1 - child entity may only be a child of one parent entity, and may not ever belong to a different parent.
rule2- the child entity can not exist without its parent.

The the orphanRemoval element causes the child entity to be removed when the relationship between the parent and the child is broken. This can be done in 2 ways

1 setting to null the attribute that holds the related entity
2. in the one-to-many case you can remove the child entity from the collection.

The provider is then responsible for removing the orphaned child entity.

Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

Just for the sake of being totally complete lets talk about @OnDelete(action = OnDeleteAction.CASCADE) . By the way I tested this an on my machine it DOES put a cascade delete constraint on the generated DDL. This is actually required for it to work properly. Note this is a hibernate specific annotation and not a JPA one.

So looking at the code below:



When entityManager.remove(division); is executed there will be 4 SQL delete statements executed one on the division and 3 on the Item table.

Now if we add that annotation to our relationship.



That same code will execute only one delete statement on the division table. Since the cascade constraint is assumed to be in the ddl the referenced rows in the Item table will be removed along with it.
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
if i remove the annotations from item like this:


the type of the feild division created in the ddl is tinyblob :s and their for it is not recongnised in my program!

oh and when i try to use it with the old database, then i can't list the divisions using SessionFactory.getCurrentSession().createQuery("FROM Division").list();

in both cases i get


août 26, 2012 10:44:27 AM org.hibernate.type.NullableType nullSafeGet
Infos: could not read column value from result set: division2_0_; could not deserialize
août 26, 2012 10:44:27 AM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
Grave: Error Rendering View[/listDivision.xhtml]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DivisionBean': Invocation of init method failed; nested exception is org.hibernate.type.SerializationException: could not deserialize


i'm starting to think their must be somthing else that i am doing wrong, that causes the child entitys not to be deleted with the parent entity. is their any other reason that can cause this problem?
thank you
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

Why did you change it to that? In my example I have division like this




Item like this



You took of the @ManyToOne off of division.
taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
i chenged it because someone suggested it!

but anyway it works now , i used the example of Bill Gorder (defenetly learned a couple of things) and it worked, so thank you a lot and to everybody else.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1680
    
    7

I am glad you got if working

One last bit of advice for you. Joshua Bloch author of Effective Java was asked if he could give one piece of advice to software developers what would it be? He responded "when in doubt leave it out". Apply this advice to cascade rules as well. It is so easy to just write CascadeType.ALL but that is many times not what you want. Add them one by one when you need them. If you end up needing them all then you can save yourself a little verbosity and add the CascadeType.ALL rule.

taylor kiani
Greenhorn

Joined: Aug 17, 2012
Posts: 15
i will keep that in mind .
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: hibernat creating the tables without cascade