Sunday, 15 May 2011

java - Foreign key update anomaly: foreign keys set to null in Hibernate one-to-many relationship -



java - Foreign key update anomaly: foreign keys set to null in Hibernate one-to-many relationship -

i finding when parent table in one-to-many relationship updated, foreign keys of dependent info on kid table beingness set null leaving orphaned records on kid table.

i have 2 java classes annotated hibernate tags. parent table is:

@entity @table(name = "person") public class person implements serializable { // attributes. @id @column(name="person_id", unique=true, nullable=false) @generatedvalue(strategy=generationtype.auto) private integer personid; @column(name="name", nullable=false, length=50) private string name; @column(name="address", nullable=false, length=100) private string address; @column(name="telephone", nullable=false, length=10) private string telephone; @column(name="email", nullable=false, length=50) private string email; @onetomany(cascade=cascadetype.all, fetch = fetchtype.lazy) @joincolumn(name="person_id") private list<book> books;

and kid table is:

entity @table(name = "book") public class book implements serializable { // attributes. @id @column(name="book_id", unique=true, nullable=false) @generatedvalue(strategy=generationtype.auto) private integer bookid; @column(name="author", nullable=false, length=50) private string author; @column(name="title", nullable=false, length=50) private string title; @column(name="description", nullable=false, length=500) private string description; @column(name="onloan", nullable=false, length=5) private string onloan; // @manytoone // private person person;

but when update issued on person, books records related parent set null.

the book table is:

create table book ( book_id integer not null generated identity (start 1, increment 1), author varchar(50) not null, title varchar(100) not null, description varchar(500) not null, onloan varchar(5) not null, person_id integer, constraint primary_key_book primary key(book_id), constraint foreign_key_book foreign key(person_id) references person(person_id))

and update method in person controller is:

@requestmapping(value = "/profile", method = requestmethod.post) public string postprofile(@modelattribute("person") person person, bindingresult bindingresult, model model) { logger.info(personcontroller.class.getname() + ".postprofile() method called."); personvalidator.validate(person, bindingresult); if (bindingresult.haserrors()) { homecoming "view/profile"; } else { personservice.update(person); model.addattribute("person", person); homecoming "view/options"; } }

and actual dao level method is:

@override public void update(person person) { logger.info(persondaoimpl.class.getname() + ".update() method called."); session session = sessionfactory.opensession(); transaction transaction = session.gettransaction(); seek { transaction.begin(); session.update(person); transaction.commit(); } catch(runtimeexception e) { utils.printstacktrace(e); transaction.rollback(); throw e; } { session.close(); } }

so i'm assuming update cause of issue why?

i have tried merge, persist , saveorupdate methods alternatives no avail.

concerning fact book table has no annotation @manytoone, disabling tag way in lazy fetching work.

this case seems similar hibernate 1 many:"many" side record's foreign key updated null automatically , hibernate many 1 updating foreign key null, if adopt changes specified classes in these questions own tables, application refuses compile seemingly because of problems utilize of mappedby in person table.

any advice welcome.

controller method changed to:

// validates , updates changes made person on profile.jap @requestmapping(value = "/profile", method = requestmethod.post) public string postprofile(@modelattribute("person") person person, bindingresult bindingresult, model model) { logger.info(personcontroller.class.getname() + ".postprofile() method called."); // validate person. personvalidator.validate(person, bindingresult); if (bindingresult.haserrors()) { homecoming "view/profile"; } else { // current person. person currperson = personservice.get(person.getpersonid()); // set books updated person. person.setbooks(currperson.getbooks()); personservice.update(person); model.addattribute("person", person); homecoming "view/options"; } }

and works.

i assume postprofile() method receives person instance contains id, name, address etc. of person, posted web form, list of books null or empty.

and you're telling hibernate save person. you're telling hibernate person, identified given id has new name, new address, new email, ... , new list of books happens empty, , should saved database.

so hibernate you're telling do: saves new state of person. , since new person doesn't have book, books owned become owned nobody.

you'll have actual, persistent person entity database, , re-create fields should modified new person persistent one.

or you'll have pre-load persistent person database , create spring populate persistent person instead of creating new instance per scratch. see http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#mvc-ann-modelattrib-methods.

java sql hibernate one-to-many updates

No comments:

Post a Comment