Thursday 15 April 2010

java - Ebean partially not saving ManyToOne association -



java - Ebean partially not saving ManyToOne association -

preamble

i struggling unusual problem. trying create "web application boostrap" procedure - run app, fill in initial db, enhancements, , ready serve.

i have table 40000+ records of stuff. have table 10000+ records of instruction.

each stuff item has instruction. -> stuff-instruction manytoone relationship.

the steps of application startup are:

fill in stuff items, not initialize instruction. fill in instructions try associate stuff instructions

now how step 3:

public class associatejob { //todo - !! there gaps in processing! why?? private static final int page_size = 100; /** * best effort associate stuff , instructions * * @return count of orphaned (instruction == null) stuffs */ public int associate() { paginglist<stuff> stuffs = stuff.find.findpaginglist(page_size); homecoming processpaginglist(stuffs); } private int processpaginglist(paginglist<stuff> pages) { int countnull = 0; (int page = 0; page < pages.gettotalpagecount(); page++) { page<stuff> stuffspage = pages.getpage(page); countnull += processpage(stuffspage); } homecoming countnull; } private int processpage(page<stuff> stuffspage) { list<stuff> list = stuffspage.getlist(); homecoming processlist(list); } private int processlist(list<stuff> list) { int countnull = 0; ebeanserver server = ebean.getserver(null); transaction tx = begintransaction(); set<string> fields = new hashset<>(); fields.add("instruction"); (stuff d : list) { instruction = instruction.bynameandform(d.name, d.form); if (i == null) { countnull++; continue; } d.instruction = i; server.update(d, fields, tx); } commit(tx); homecoming countnull; } private transaction begintransaction() { ebeanserver server = ebean.getserver(null); transaction transaction = server.begintransaction(); transaction.setbatchsize(100); transaction.setpersistcascade(false); homecoming transaction; } private void commit(transaction transaction) { transaction.commit(); }

}

when step 3 complete, associatejob.associate() method returns 6 - 6 stuff items left without instruction, i'll have specify later manually.

problem

in fact, many associations left unsaved. when execute:

int countnull = stuff.find.where().eq("instruction", null).findrowcount();

i receive over 12 000 stuff items without instruction.

question

why happening? how can solve it?

for sticking temporal crunchy workaround (creating job associate stuff stuff.instruction == null), bad, , possibly-ebean-issue going impact future internal processess.

thanks rob's hint here, came simple , elegant solution of problem:

public class associatejob { public int associate() { string sql = "update stuff s set instruction_id = " + "(select i.id instruction " + "i.name s.name , i.form s.form )" + " instruction_id null"; sqlupdate update = ebean.createsqlupdate(sql); homecoming update.execute(); } }

so whole batch processing done via 1 big update operation, way didn't think of, blinded elegance of object-oriented approach of orm.

java database playframework-2.0 ebean

No comments:

Post a Comment