I'm having an issue with my application, and I'm hoping you guys will be able to help. Please forgive typos and obvious errors, I'm having to retype from a non-internet connected network.
A contrived example is:
@Entity public class Salesman { private String name; @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.All) private Map<Company, Collection<Integer>> companyTargets; } @Entity public class Company { private String name; }
For the sake of the example, each salesman has many numerical targets for each company. Two salesman will have a different set of numerical targets for the same company.
The application is an unusual one, in that it keeps all objects in memory at all times, in a Detached state (I realise the implications here, there are good reasons for this approach). All potential changes are checked with application logic before being committed to the database, so a commit will never fail. Any time an object is modified it is checked that the modification would be valid, and then committed.
Lets assume I have many Salesmen, and add a new Company. Each salesman is given many numerical targets for the new company. I then need to merge each salesman back into the database to keep it in step. The code i have to do this is akin to:
EntityManager em = emf.getEntityManager(); em.getTransaction().begin(); Company company = new Company("new"); em.persist(company); em.getTransaction().commit(); giveSalesmenNewTargets(salesmen, company); for (Salesman s : salesmen) em.merge(s);
This appears to have the effect of checking and merging the entire companyTargets map for every salesman, and because there are thousands of Company objects attached to each Salesman, and each Salesman has hundreds of targets for each Company, this merge takes a significant amount of time.
What I would Ideally like to happen would be for there to be some way to re-attach the detached salesman with some form of 'I promise I haven't changed anything' flag, then to perform the modification, and for things that change after the re-attach happens to be changed in the database. Is there some way to achieve this? It might look something like:
EntityManager em = emf.getEntityManager(); em.getTransaction().begin(); Company company = new Company("new"); em.persist(company); em.getTransaction().commit(); em.getTransaction.begin(); for (Salesman s : salesmen) em.uncheckedMerge(s); giveSalesmenNewTargets(salesmen, company); em.getTransaction().commit();
Thanks very much,
Phil